Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this the correct way to atomically read and write a bool?

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.

  • The functions are static

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?

like image 289
Kostolma Avatar asked Sep 04 '25 17:09

Kostolma


1 Answers

__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.

like image 105
Damon Avatar answered Sep 06 '25 13:09

Damon