A boolean flag is toggled by two threads. Does the following code make sense?
static bool ATOMIC_BOOL_READ( volatile bool& var )
{
return __sync_fetch_and_or(&var, 0);
}
static void ATOMIC_BOOL_WRITE(volatile bool& var, bool newval )
{
__sync_bool_compare_and_swap( &var, !newval, newval);
}
Note a few things:
I am passing in a bool reference. Make sense?
For kick's sake, I am also declaring it volatile.
Update:
The fundamental question I want to ask is: Whats the difference between atomicity and memory barrier? If Thread A is executing an atomic builtin on variable foo, then Thread B cannot do ANYTHING on variable foo; hence creating a memory barrier?
__sync_bool_compare_and_swap
is correct, but possibly much more expensive than necessary.
It depends what you need. __sync_lock_test_and_set
will be cheaper (and guaranteeed to be atomic), but it does not report back if the operation was "successful" insofar as the value is what was expected (it's always "successful" anyway, and you do get the value back too, it just doesn't fail if it's not what you said). However, this is some information that is not always interesting.
Instead of the atomic builtins, you could use std::atomic<bool>
if you compile in C++0x mode, which offers .load()
and .store()
. These functions are possibly more efficient (either exploiting knowledge that some operation is atomic anyway, or inserting barriers, or using special operations, or whatever), and your code is more portable (and more obvious).
Further, on pretty much every architecture, you can also expect (thought there is no guarantee!) a write to a bool being atomic anyway.
And... it really depends. If for example you just want to set a flag in one thread, and just want to see whether it's set in the other thread and it does not matter if it maybe takes a few more microseconds before this is realized, you can just assign the variable regardless of any atomicity.
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