No, it doesn't. The test_and_set() operation itself is atomic, so it doesn't matter how deep different threads' call-stacks are.
To demonstrate this, consider the base case where the atomic_flag object is "exposed" directly:
static atomic_flag flag = ATOMIC_FLAG_INIT; void threadMethod() { bool wasFirst = !flag.test_and_set(); if( wasFirst ) cout << "I am thread " << this_thread::get_id() << ", I was first!" << endl; else cout << "I am thread " << this_thread::get_id() << ", I'm the runner-up" << endl; }
If two threads enter threadMethod - with one thread (t1) slightly before the other (t2) then we can expect the console output to be the following (in the same order):
I am thread t1, I was first! I am thread t2, I'm the runner-up
Now if both threads enter simultaneously, but t2 is a microsecond ahead of t1, but t2 then becomes slower than t1 as it writes to stdout, then the output would be:
I am thread t1, I'm the runner-up I am thread t2, I was first!
...so the call to test_and_set was still atomic, even though the output is not necessarily in the expected order.
Now if you were to wrap flag in another method (not inlined, just to be sure), like so...
__declspec(noinline) bool wrap() { return !flag.test_and_set(); } void threadMethod() { bool wasFirst = wrap(); if( wasFirst ) cout << "I am thread " << this_thread::get_id() << ", I was first!" << endl; else cout << "I am thread " << this_thread::get_id() << ", I'm the runner-up" << endl; }
...then the program would not behave any differently - because the false or true return bool value from test_and_set() will still be in each thread's stacks. Ergo, wrapping a atomic_flag does not change its atomicity.
ready. Could you say how you usereadyas I suspect this may be the real issue?isReady, likewhile (!isReady()) do_something(). Does it make sense?