[llvm] r219638 - Removing the static destructor from ManagedStatic.cpp by controlling the allocation and de-allocation of the mutex.
Chris Bieneman
beanz at apple.com
Wed Oct 22 16:07:46 PDT 2014
I have managed to reproduce this and I have a workaround (although it is not ideal). I’ll be sending patches out for review shortly. The root cause of the problem is a bug in Microsoft’s implementation of std::call_once. I found a public bug report tracking the issue here:
http://connect.microsoft.com/VisualStudio/feedbackdetail/view/811192/std-call-once-hangs <http://connect.microsoft.com/VisualStudio/feedbackdetail/view/811192/std-call-once-hangs>
The core issue of the bug is that std::call_once can’t be called from a static initializer. Unfortunately the bug report doesn’t say when or where they fixed it, but I expect it was fixed in a newer version of the C++ runtime. The problem then becomes that I don’t believe LLVM has a precedent for requiring specific versions of the C++ redistributable package (which I think is where the fix would be).
Thanks,
-Chris
> On Oct 17, 2014, at 1:07 PM, Chris Bieneman <cbieneman at apple.com> wrote:
>
> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20141022/b7a6b118/attachment.html>
More information about the llvm-commits
mailing list