This method (I realize the function might need some extra parameters):
void waitUntilNotEqual(volatile int* addr, int value)
{
while (*addr == value) {}
}
I'm pretty new to the use of futexes but here's a solution that I think should work. Just be warned that I haven't tested this at all and it could be made faster with a few more tweaks.
void waitUntilNotEqual(volatile int* addr, int value) {
while (*addr == value) {
futex(addr, FUTEX_WAIT, value, 0, 0, 0);
}
}
void changeValue (volatile int* addr, int newValue) {
int oldValue = *addr;
if (oldValue != newValue) {
*addr = newValue;
futex(addr, FUTEX_WAKE, INT_MAX, 0, 0, 0);
}
}
In order for this to work properly, all modification of the address passed to waitUntilNotEqual
should be done through changeValue
. The INT_MAX
value in the FUTEX_WAKE
call indicates that it should wake all threads waiting on this futex. The if statement in the changeValue
function is an optimisation that avoids pointless wakeups. Finally, the FUTEX_WAIT
call needs to be kept in a loop because it might return spuriously from signals.
I should also point out that you didn't give much details about the problem you're trying to solve which means that this piece of code is probably only correct for the very simplest of use cases. If you want something better adapted to your current problem then I need more details (number of threads, context in which waitUntilNotEqual
and changeValue
is called, number of possible concurrent threads in waitUntilNotEqual
or changeValue
, etc.)
If you're interested in learning more about how to properly use futexes, I recommend the Futexes Are Tricky paper.
See the man page: http://ds9a.nl/futex-manpages/futex2.html and let us know if there's something you still need after that. One thing I am not sure of from your question is whether you intend to have another function that informs this one that the value has been updated, or if you prefer to use timeouts.