Is the following code standards compliant? (or can it be made compliant without making x
atomic or volatile
?)
This is similar to an earlier question, however I would like a citation to the relevant section of the C++ standard, please.
My concern is that atomic store()
and load()
do not provide sufficient compiler barriers for the non-atomic variables (x
in the example below) to have correct release and acquire semantics.
My goal is to implement lock-free primitives, such as queues, that can transfer pointers to regular C++ data structures between threads.
#include <atomic>
#include <chrono>
#include <iostream>
#include <thread>
int x; // regular variable, could be a complex data structure
std::atomic<int> flag { 0 };
void writer_thread() {
x = 42;
// release value x to reader thread
flag.store(1, std::memory_order_release);
}
bool poll() {
return (flag.load(std::memory_order_acquire) == 1);
}
int main() {
x = 0;
std::thread t(writer_thread);
// "reader thread" ...
// sleep-wait is just for the test.
// production code calls poll() at specific points
while (!poll())
std::this_thread::sleep_for(std::chrono::milliseconds(50));
std::cout << x << std::endl;
t.join();
}