I want to use atomic compare and swap, but instead of equal to, I want to swap only if the memory location is not equal to the old value. Is it possible in C?
In computer science, compare-and-swap (CAS) is an atomic instruction used in multithreading to achieve synchronization. It compares the contents of a memory location with a given value and, only if they are the same, modifies the contents of that memory location to a new given value.
In comparison to Test and Set Instruction, the compare and swap instruction operates on three operands. Here the operand value is assigned to a new value only if the expression (*value == expected) is true.
Compare and swap is a technique used when designing concurrent algorithms. The approach is to compare the actual value of the variable to the expected value of the variable and if the actual value matches the expected value, then swap the actual value of the variable for the new value passed in.
compareAndSet() is an inbuilt method in java that sets the value to the passed value in the parameter if the current value is equal to the expected value which is also passed in the parameter. The function returns a boolean value which gives us an idea if the update was done or not.
How about this:
void compare_and_swap_if_not_equal(word_t const required_non_value, word_t const new_value, word_t* ptr_to_shared_variable) {
for (;;) {
word_t const snapshot_value = *ptr_to_shared_variable;
if (required_non_value == snapshot_value) {
break;
// or (sleep and) 'continue;', if you want to wait for the stored value to be different
// -- but you might of course miss a transient change to a different state and back.
} else {
if (compare_and_swap_if_equal(ptr_to_shared_variable, snapshot_value, new_value)) {
// we know the stored value was different; if this 'theory' still matches reality: swap! done!
break;
}
}
}
}
Untested. Uncompiled. The 'const' used because I like it that way :). 'word_t' is a type placeholder, I don't know what the real type should be. And I don't know how what 'compare_and_swap_if_equal' is called in stdatomic.h.
(added) atomic_compare_exchange_weak() is the ticket. For some reason, it takes a pointer to the 'expected' argument, so you'll have to modify above code to
if (atomic_compare_exchange_weak(ptr_to_shared_variable, &snapshot_value, new_value)) ...
The 'weak' version should work in the above code; returning 'false' spuriously will only add another trip around the loop. Still uncompiled, untested; don't rely on this code at home.
It depends on your architecture, but in general it is not possible to do this in C.
Typically compare and swap is implemented with an instruction that atomically loads from a location in memory and stores a value to that location if the location in memory matches some existing value that you specify.
At least on x86 there is no provision for only doing this load if the values don't match. Also it's not clear why you would want to do something like that. Perhaps another architecture would support something like this, but that would be architecture dependent, not something that could be done in C in a portable way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With