Basically what I am looking for is something that will accomplish the following logic atomically.
#define FAILED 1
#define SUCCESS 0
int foo (uint64_t * src, uint64_t * dst, uint64_t expected) {
if (*src == expected) {
*dst = *src;
return SUCCESS;
}
return FAILURE;
}
For this particular use case expected == 0
in all cases and *dst
CANNOT be modified by any other thread. *src
, however can be modified by other threads concurrently (those other threads CAN be on another cores otherwise I could use restartable sequences)
For this to be correct *dst
CANNOT be modified if *src != expected
(with expected == 0
).
I have the invariant *src != *dst
except if *src == *dst == 0
(this might be useful for finding a solution).
Finally if it enables any potential solutions I can gurantee that *src
and *dst
are either on the same cache line or different cache lines.
I don't believe any of the builtin atomic operation (https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html) can achieve this so I think the only way to do this will be with some inline assembly using the lock
prefix or to use some side effect of some function (i.e something along the lines of the fact that CAS will set expected on failure).
The summarize I am looking for either a way to implement a custom atomic operation with inline asm or some way I can use bultin atomics to achieve this.
Thank you!