I have the following code being executed on a single thread (written in C 20):
std::atomic_bool is_ready{};
void SetReady() {
is_ready.store(true, std::memory_order_release);
is_ready.notify_all();
}
Other threads execute the text listed below:
void Wait() {
is_ready.wait(false, std::memory_order_acquire);
}
As I know, release memory order doesn't ensure that the operations located after it will not be reordered by a compiler. So, can I place notify_all()
after store()
with release memory order? Is it safe? Just I have some thoughts that store()
may be sequenced before notify_all()
and hence may not be reordered.
CodePudding user response:
The memory orders are irrelevant here. They only affect ordering of memory access other than on the atomic itself and you have none.
The compiler cannot reorder the notify_all
call before the store in any case, because notify_all
is specified to wake up all waiting operations on the atomic which are eligible to be unblocked.
Which these are depends on whether, in the global modification order of the atomic, the last store which happens-before the call to notify_all
is ordered after the store observed by the waiting thread when it blocked.
In your shown code the true
store is sequenced-before the notify_all
call (in the same thread), which implies that the store happens-before the call, but if the lines were switched, then that wouldn't be the case anymore.
Moving the notify_all
before the store would thus potentially change the set of waiting operations which are eligible to be unblocked.
If the compiler was allowed to do that, then the waiting/notification mechanism would be pretty useless. This is also the same as for other operations on the same atomic in the same thread (or really any operations on the same storage location in the same thread). The compiler cannot reorder these either.
So yes, it is safe and the Wait
thread will not wait forever. (I am assuming that the initialization std::atomic_bool is_ready{};
is happening before either of the shown thread functions start execution.)