In the following code, is using atomics necessary to guarantee race-free semantics on all platforms or does the use the use of a promise.set_value/future.wait imply some kind of implicit memory barrier that would allow me to rely on the flag write having become visible to the outer thread?
std::atomic_bool flag{false}; // <- does this need to be atomic?runInThreadPoolBlocking([&]() { // do something flag.store(true);});if (flag.load()) // do something// simplified runInThreadPoolBlocking implementationtemplate <typename Callable>void runInThreadPoolBlocking(Callable func){ std::promise<void> prom; auto fut = prom.get_future(); enqueueToThreadPool([&]() { func(); prom.set_value(); }); fut.get();}
In general, are there any "implicit" memory barriers guaranteed by the standard for things like thread.join() or futures?