[PATCH] Removing the static initializer in ManagedStatic.cpp by using llvm_call_once to initialize the ManagedStatic mutex.
Reid Kleckner
rnk at google.com
Thu Oct 30 11:08:42 PDT 2014
So, bad news, `std::atomic<int>` has a non-trivial default constructor in the MSVC STL. This means the code `void foo() { static std::atomic<int> flag; }` uses a non-threadsafe guard variable to initialize `flag`. Worse, the guard variable is a bitfield, so it is very much not threadsafe. See the code for foo here:
mov eax,dword ptr [?$S1@?1??foo@@YAXXZ at 4IA]
test al,1
jne initialized
or eax,1
mov ecx,offset ?flag@?1??foo@@YAXXZ at 4U?$atomic at H@std@@A
mov dword ptr [?$S1@?1??foo@@YAXXZ at 4IA],eax
xor eax,eax
xchg eax,dword ptr [ecx]
initialized:
ret
So... I'm running out of ideas. :( We can wait 3 years and wait for MSVC 14 to be our baseline, and then the problem of thread-safe static initialization will go away.
http://reviews.llvm.org/D5922
More information about the llvm-commits
mailing list