ActivityManager uses volatile variables as memory barriers:
interpreter/concurrency/ActivityManager.cpp:53 Activity *volatile ActivityManager::currentActivity = OREF_NULL;
interpreter/concurrency/ActivityManager.cpp:56 volatile bool ActivityManager::sentinel = false;
with comments such as:
// the setting of the sentinel variables acts as a memory barrier to
// ensure that the assignment of currentActivitiy occurs precisely at this point.
That guarantee does not exist in C++. volatile prevents the compiler from eliding or coalescing
accesses to that specific object; it does not order surrounding non-volatile accesses and emits no
CPU fence. Both the compiler and the processor remain free to reorder across it.
x86's strong store ordering hides most of the consequences, which is likely why this has survived.
It would not hold on ARM or POWER.
The standard tools are std::atomic<bool> / std::atomic<Activity*> (sequentially consistent by
default), or std::atomic_thread_fence(std::memory_order_seq_cst) where a standalone fence is meant.
The codebase already builds as -std=gnu++11, so <atomic> is available.
Caveat for any conversion: the Windows build force-disables exceptions
(CMakeLists.txt:531 rewrites /EHsc to /EHsc-), which interacts with adopting std::mutex
elsewhere, though std::atomic itself is exception-free.
Anonymous
Fixed in r13183.
Commit [r13183]
Related
Commit: [r13183]