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

Chris Bieneman cbieneman at apple.com
Fri Oct 17 13:07:17 PDT 2014


I’ve been having trouble reproducing this. Admittedly this is probably mostly due to my total lack of familiarity with Windows development. Any help tracking this down is greatly appreciated.

Thanks,
-Chris

> On Oct 14, 2014, at 9:30 AM, Aaron Ballman <aaron at aaronballman.com> wrote:
> 
> 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