[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