سؤال

Let's say I have 1 counter starting at value 2, some non-atomic boolean variable and 4 threads.

//Initialization (happens before any thread execute).
std::atomic<int> count = ATOMIC_VAR_INIT(2);
bool someBoolean = false;

Thread 1:

count.fetch_sub(1, std::memory_order_release);

Thread 2:

someBoolean = true;
count.fetch_sub(1, std::memory_order_release);

Thread 3:

while(count.load(std::memory_order_acquire) != 0);
//Now, we're out of the while loop...
assert(someBoolean);

Thread 4:

while(std::atomic_thread_fence(std::memory_order_acquire), 
      count.load(std::memory_order_relaxed) != 0);
//Now, we're out of the while loop...
assert(someBoolean);

Is it possible that the assertions at Thread 3 or Thread 4 may fire?

هل كانت مفيدة؟

المحلول

Thread 4 may fire the assertion because you use the load operation and the memory fence in incorrect order. You have to load the count variable first, then place the memory acquire fence.
In general case you have to place a Release fence before writing to a synchronization flag and place an Acquire fence after reading it.

You can find the detailed explanation and examples of Acquire/Release memory fences in this post from the great Jeff Preshing's blog: http://preshing.com/20130922/acquire-and-release-fences/

Thread 3 (and Thread 4 after fixing the function call order) will not fire an assertion because synchronize-with relationship between threads is established correctly.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top