[PATCH] Removing the static initializer in ManagedStatic.cpp by using llvm_call_once to initialize the ManagedStatic mutex.
Chris Bieneman
beanz at apple.com
Thu Oct 23 17:09:28 PDT 2014
It sounds like David's complaints are performance related not correctness. Unfortunately his suggested implementation doesn't really cover the needs for this. The hand-rolled solution is basically filling in on Windows where we aren't guaranteed to have <mutex>, <thread>, or <atomic>.
There are definitely more performant ways to implement the hand rolled solution, but it should be safe as implemented. That said, I will make adjustments to the implementation and submit updated patches for review.
================
Comment at: include/llvm/Support/Threading.h:70
@@ +69,3 @@
+ // Visual Studio bug id #811192.
+ static volatile sys::cas_flag initialized = 0;
+ sys::cas_flag old_val = sys::CompareAndSwap(&initialized, 1, 0);
----------------
majnemer wrote:
> `volatile` doesn't really make sense here.
Why not? Having this be volatile actually alleviates the possibility of the compiler optimizing away loads.
================
Comment at: include/llvm/Support/Threading.h:71
@@ +70,3 @@
+ static volatile sys::cas_flag initialized = 0;
+ sys::cas_flag old_val = sys::CompareAndSwap(&initialized, 1, 0);
+ if (old_val == 0) {
----------------
majnemer wrote:
> This is very expensive, you are performing a RMW operation even if nothing has changed.
Sure. For performance this should only execute if not already initialized.
================
Comment at: include/llvm/Support/Threading.h:77-82
@@ +76,8 @@
+ } else {
+ sys::cas_flag tmp = initialized;
+ sys::MemoryFence();
+ while (tmp != 2) {
+ tmp = initialized;
+ sys::MemoryFence();
+ }
+ }
----------------
majnemer wrote:
> Let's assume that loading `initialized` will somehow turn into a relaxed load. Why bother with the fence? You could just fence after:
> while (initialized != 2);
> sys::MemoryFence();
>
> This will result in far, far fewer fences should this ever be contended.
The point of making initialized volatile is so that the compiler will emit a load for the while loop. If you're loading with each iteration of the loop is the fence really needed at all?
It shouldn't be for correctness.
http://reviews.llvm.org/D5922
More information about the llvm-commits
mailing list