[llvm] r219638 - Removing the static destructor from ManagedStatic.cpp by controlling the allocation and de-allocation of the mutex.

Aaron Ballman aaron at aaronballman.com
Tue Oct 14 09:30:49 PDT 2014


On Tue, Oct 14, 2014 at 12:28 PM, Chris Bieneman <beanz at apple.com> wrote:
> Thank you. I will also see if I can reproduce the hang.

As a data point, I am able to reproduce the hang on Windows 7 with an
x86, MSVC-built clang by running the test suite. It is somewhere in
the arcmt-test and c-index-test suites, judging by how many tests
hung.

~Aaron

>
> -Chris
>
>> On Oct 14, 2014, at 9:11 AM, NAKAMURA Takumi <geek4civic at gmail.com> wrote:
>>
>> Excuse me, I have reverted it in r219687.
>>
>> It caused hangup in msc builder, probably deadlock in clang's
>> arcmt-test and c-index-test.
>> http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/10976
>>
>> I will investigate tomorrow.
>>
>> 2014-10-14 7:37 GMT+09:00 Chris Bieneman <beanz at apple.com>:
>>> Author: cbieneman
>>> Date: Mon Oct 13 17:37:25 2014
>>> New Revision: 219638
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=219638&view=rev
>>> Log:
>>> Removing the static destructor from ManagedStatic.cpp by controlling the allocation and de-allocation of the mutex.
>>>
>>> This patch adds a new llvm_call_once function which is used by the ManagedStatic implementation to safely initialize a global to avoid static construction and destruction.
>>>
>>> Modified:
>>>    llvm/trunk/include/llvm/Support/Threading.h
>>>    llvm/trunk/lib/Support/ManagedStatic.cpp
>>>
>>> Modified: llvm/trunk/include/llvm/Support/Threading.h
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Threading.h?rev=219638&r1=219637&r2=219638&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/Support/Threading.h (original)
>>> +++ llvm/trunk/include/llvm/Support/Threading.h Mon Oct 13 17:37:25 2014
>>> @@ -15,6 +15,10 @@
>>> #ifndef LLVM_SUPPORT_THREADING_H
>>> #define LLVM_SUPPORT_THREADING_H
>>>
>>> +#if !defined(__MINGW__)
>>> +#include <mutex>
>>> +#endif
>>> +
>>> namespace llvm {
>>>   /// Returns true if LLVM is compiled with support for multi-threading, and
>>>   /// false otherwise.
>>> @@ -33,6 +37,20 @@ namespace llvm {
>>>   /// the thread stack.
>>>   void llvm_execute_on_thread(void (*UserFn)(void*), void *UserData,
>>>                               unsigned RequestedStackSize = 0);
>>> +
>>> +template <void (*UserFn)(void)> void llvm_call_once() {
>>> +
>>> +#if !defined(__MINGW__)
>>> +  static std::once_flag flag;
>>> +  std::call_once(flag, UserFn);
>>> +
>>> +#else
>>> +  struct InitOnceWrapper {
>>> +    InitOnceWrapper() { UserFn(); }
>>> +  };
>>> +  static InitOnceWrapper InitOnceVar;
>>> +#endif
>>> +}
>>> }
>>>
>>> #endif
>>>
>>> Modified: llvm/trunk/lib/Support/ManagedStatic.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/ManagedStatic.cpp?rev=219638&r1=219637&r2=219638&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Support/ManagedStatic.cpp (original)
>>> +++ llvm/trunk/lib/Support/ManagedStatic.cpp Mon Oct 13 17:37:25 2014
>>> @@ -16,16 +16,22 @@
>>> #include "llvm/Support/Atomic.h"
>>> #include "llvm/Support/Mutex.h"
>>> #include "llvm/Support/MutexGuard.h"
>>> +#include "llvm/Support/Threading.h"
>>> #include <cassert>
>>> using namespace llvm;
>>>
>>> static const ManagedStaticBase *StaticList = nullptr;
>>> +static sys::Mutex *ManagedStaticMutex = nullptr;
>>>
>>> -static sys::Mutex& getManagedStaticMutex() {
>>> +static void initializeMutex() {
>>> +  ManagedStaticMutex = new sys::Mutex();
>>> +}
>>> +
>>> +static sys::Mutex* getManagedStaticMutex() {
>>>   // We need to use a function local static here, since this can get called
>>>   // during a static constructor and we need to guarantee that it's initialized
>>>   // correctly.
>>> -  static sys::Mutex ManagedStaticMutex;
>>> +  llvm_call_once<initializeMutex>();
>>>   return ManagedStaticMutex;
>>> }
>>>
>>> @@ -33,7 +39,7 @@ void ManagedStaticBase::RegisterManagedS
>>>                                               void (*Deleter)(void*)) const {
>>>   assert(Creator);
>>>   if (llvm_is_multithreaded()) {
>>> -    MutexGuard Lock(getManagedStaticMutex());
>>> +    MutexGuard Lock(*getManagedStaticMutex());
>>>
>>>     if (!Ptr) {
>>>       void* tmp = Creator();
>>> @@ -83,8 +89,13 @@ void ManagedStaticBase::destroy() const
>>>
>>> /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
>>> void llvm::llvm_shutdown() {
>>> -  MutexGuard Lock(getManagedStaticMutex());
>>> +  {
>>> +    MutexGuard Lock(*getManagedStaticMutex());
>>> +
>>> +    while (StaticList)
>>> +      StaticList->destroy();
>>> +  }
>>>
>>> -  while (StaticList)
>>> -    StaticList->destroy();
>>> +  delete ManagedStaticMutex;
>>> +  ManagedStaticMutex = nullptr;
>>> }
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list