Change interface of atomic compare and swap
The old atomic compare and swap operations (vtkm::AtomicCompareAndSwap
and vtkm::exec::AtomicArrayExecutionObject::CompareAndSwap
) had an
order of arguments that was confusing. The order of the arguments was
shared pointer (or index), desired value, expected value. Most people
probably assume expected value comes before desired value. And this
order conflicts with the order in the std
methods, GCC atomics, and
Kokkos.
Change the interface of atomic operations to be patterned off the
std::atomic_compare_exchange
and std::atomic<T>::compare_exchange
methods. First, these methods have a more intuitive order of parameters
(shared pointer, expected, desired). Second, rather than take a value
for the expected and return the actual old value, they take a pointer to
the expected value (or reference in AtomicArrayExecutionObject
) and
modify this value in the case that it does not match the actual value.
This makes it harder to mix up the expected and desired parameters.
Also, because the methods return a bool indicating whether the value was
changed, there is an additional benefit that compare-exchange loops are
implemented easier.
For example, consider you want to apply the function MyOp
on a
sharedValue
atomically. With the old interface, you would have to do
something like this.
T oldValue;
T newValue;
do
{
oldValue = *sharedValue;
newValue = MyOp(oldValue);
} while (vtkm::AtomicCompareAndSwap(sharedValue, newValue, oldValue) != oldValue);
With the new interface, this is simplfied to this.
T oldValue = *sharedValue;
while (!vtkm::AtomicCompareExchange(sharedValue, &oldValue, MyOp(oldValue));
Fixes #567 (closed).