[llvm] r220932 - Removing the static initializer in ManagedStatic.cpp by using llvm_call_once to initialize the ManagedStatic mutex.

Chris Bieneman beanz at apple.com
Tue Nov 4 12:43:45 PST 2014


There is another thread discussing similar issues on PPC. I’m going to cc you into that thread too. I suspect we will need to use the hand rolled solution that is implemented for Windows on more platforms.

-Chris

> On Nov 4, 2014, at 12:12 AM, Jiangning Liu <liujiangning1 at gmail.com> wrote:
> 
> BTW, my OS is debian and "uname -a" shows,
> 
> Linux 3.15.0-rc8+ #9 SMP PREEMPT aarch64 GNU/Linux
> 
> Thanks,
> -Jiangning
> 
> 2014-11-04 16:09 GMT+08:00 Jiangning Liu <liujiangning1 at gmail.com <mailto:liujiangning1 at gmail.com>>:
> Hi Chris,
> 
> This commit triggered a llvm/clang build failure on aarch64 host machine. The error message is like,
> 
> /bin/sh: line 1: 16677 Segmentation fault ../../../../bin/clang-tblgen -gen-arm-neon -I /work/slave/performance-daily/build/tools/clang/lib/Headers -I /work/slave/performance-daily/build/lib/Target -I /work/slave/performance-daily/build/include /work/slave/performance-daily/build/tools/clang/include/clang/Basic/arm_neon.td <http://arm_neon.td/> -o /work/slave/performance-daily/build/build/tools/clang/lib/Headers/arm_neon.h.tmp
> 
> It seems pthread doesn't work well on aarch64 target, so the following code doesn't work.
> 
> +void llvm::call_once(once_flag& flag, void (*fptr)(void)) {
> +  std::call_once(flag, fptr);
> +}
> 
> Can we use the same solution as windows rather than call std::call_once directly?
> 
> Thanks,
> -Jiangning
> 
> 
> 2014-10-31 6:07 GMT+08:00 Chris Bieneman <beanz at apple.com <mailto:beanz at apple.com>>:
> Author: cbieneman
> Date: Thu Oct 30 17:07:09 2014
> New Revision: 220932
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=220932&view=rev <http://llvm.org/viewvc/llvm-project?rev=220932&view=rev>
> Log:
> Removing the static initializer in ManagedStatic.cpp by using llvm_call_once to initialize the ManagedStatic mutex.
> 
> Summary:
> This patch adds an llvm_call_once which is a wrapper around std::call_once on platforms where it is available and devoid of bugs. The patch also migrates the ManagedStatic mutex to be allocated using llvm_call_once.
> 
> These changes are philosophically equivalent to the changes added in r219638, which were reverted due to a hang on Win32 which was the result of a bug in the Windows implementation of std::call_once.
> 
> Reviewers: aaron.ballman, chapuni, chandlerc, rnk
> 
> Reviewed By: rnk
> 
> Subscribers: majnemer, llvm-commits
> 
> Differential Revision: http://reviews.llvm.org/D5922 <http://reviews.llvm.org/D5922>
> 
> Added:
>     llvm/trunk/lib/Support/Unix/Threading.inc
>     llvm/trunk/lib/Support/Windows/Threading.inc
> Modified:
>     llvm/trunk/include/llvm/Support/Threading.h
>     llvm/trunk/lib/Support/CMakeLists.txt
>     llvm/trunk/lib/Support/ManagedStatic.cpp
>     llvm/trunk/lib/Support/Threading.cpp
> 
> Modified: llvm/trunk/include/llvm/Support/Threading.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Threading.h?rev=220932&r1=220931&r2=220932&view=diff <http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Threading.h?rev=220932&r1=220931&r2=220932&view=diff>
> ==============================================================================
> --- llvm/trunk/include/llvm/Support/Threading.h (original)
> +++ llvm/trunk/include/llvm/Support/Threading.h Thu Oct 30 17:07:09 2014
> @@ -15,6 +15,14 @@
>  #ifndef LLVM_SUPPORT_THREADING_H
>  #define LLVM_SUPPORT_THREADING_H
> 
> +#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
> +
> +#if defined(LLVM_ON_UNIX)
> +#include <mutex>
> +#else
> +#include "llvm/Support/Atomic.h"
> +#endif
> +
>  namespace llvm {
>    /// Returns true if LLVM is compiled with support for multi-threading, and
>    /// false otherwise.
> @@ -33,6 +41,35 @@ namespace llvm {
>    /// the thread stack.
>    void llvm_execute_on_thread(void (*UserFn)(void*), void *UserData,
>                                unsigned RequestedStackSize = 0);
> +
> +#if defined(LLVM_ON_UNIX)
> +typedef std::once_flag once_flag;
> +#define LLVM_DEFINE_ONCE_FLAG(flag) static once_flag flag
> +#else
> +enum InitStatus {
> +  Done = -1,
> +  Uninitialized = 0,
> +  Wait = 1
> +};
> +typedef volatile sys::cas_flag once_flag;
> +
> +#define LLVM_DEFINE_ONCE_FLAG(flag) static once_flag flag = Uninitialized
> +#endif
> +
> +/// \brief Execute the function specified as a parameter once.
> +///
> +/// Typical usage:
> +/// \code
> +///   void foo() {...};
> +///   ...
> +///   LLVM_DEFINE_ONCE_FLAG(flag);
> +///   call_once(flag, foo);
> +/// \endcode
> +///
> +/// \param flag Flag used for tracking whether or not this has run.
> +/// \param UserFn Function to call once.
> +void call_once(once_flag&, void (*)(void));
> +
>  }
> 
>  #endif
> 
> Modified: llvm/trunk/lib/Support/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CMakeLists.txt?rev=220932&r1=220931&r2=220932&view=diff <http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CMakeLists.txt?rev=220932&r1=220931&r2=220932&view=diff>
> ==============================================================================
> --- llvm/trunk/lib/Support/CMakeLists.txt (original)
> +++ llvm/trunk/lib/Support/CMakeLists.txt Thu Oct 30 17:07:09 2014
> @@ -102,6 +102,7 @@ add_llvm_library(LLVMSupport
>    Unix/Program.inc
>    Unix/RWMutex.inc
>    Unix/Signals.inc
> +  Unix/Threading.inc
>    Unix/ThreadLocal.inc
>    Unix/TimeValue.inc
>    Unix/Watchdog.inc
> @@ -114,6 +115,7 @@ add_llvm_library(LLVMSupport
>    Windows/Program.inc
>    Windows/RWMutex.inc
>    Windows/Signals.inc
> +  Windows/Threading.inc
>    Windows/ThreadLocal.inc
>    Windows/TimeValue.inc
>    Windows/Watchdog.inc
> 
> Modified: llvm/trunk/lib/Support/ManagedStatic.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/ManagedStatic.cpp?rev=220932&r1=220931&r2=220932&view=diff <http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/ManagedStatic.cpp?rev=220932&r1=220931&r2=220932&view=diff>
> ==============================================================================
> --- llvm/trunk/lib/Support/ManagedStatic.cpp (original)
> +++ llvm/trunk/lib/Support/ManagedStatic.cpp Thu Oct 30 17:07:09 2014
> @@ -16,16 +16,23 @@
>  #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;
> +LLVM_DEFINE_ONCE_FLAG(mutex_init_flag);
> 
> -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;
> +  call_once(mutex_init_flag, initializeMutex);
>    return ManagedStaticMutex;
>  }
> 
> @@ -33,7 +40,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,7 +90,7 @@ 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();
> 
> Modified: llvm/trunk/lib/Support/Threading.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Threading.cpp?rev=220932&r1=220931&r2=220932&view=diff <http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Threading.cpp?rev=220932&r1=220931&r2=220932&view=diff>
> ==============================================================================
> --- llvm/trunk/lib/Support/Threading.cpp (original)
> +++ llvm/trunk/lib/Support/Threading.cpp Thu Oct 30 17:07:09 2014
> @@ -110,3 +110,10 @@ void llvm::llvm_execute_on_thread(void (
>  }
> 
>  #endif
> +
> +#if defined(LLVM_ON_UNIX)
> +#include "Unix/Threading.inc"
> +#else
> +#include "Windows/Threading.inc"
> +#endif
> +
> 
> Added: llvm/trunk/lib/Support/Unix/Threading.inc
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Threading.inc?rev=220932&view=auto <http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Threading.inc?rev=220932&view=auto>
> ==============================================================================
> --- llvm/trunk/lib/Support/Unix/Threading.inc (added)
> +++ llvm/trunk/lib/Support/Unix/Threading.inc Thu Oct 30 17:07:09 2014
> @@ -0,0 +1,5 @@
> +#include <thread>
> +
> +void llvm::call_once(once_flag& flag, void (*fptr)(void)) {
> +  std::call_once(flag, fptr);
> +}
> 
> Added: llvm/trunk/lib/Support/Windows/Threading.inc
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Threading.inc?rev=220932&view=auto <http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Threading.inc?rev=220932&view=auto>
> ==============================================================================
> --- llvm/trunk/lib/Support/Windows/Threading.inc (added)
> +++ llvm/trunk/lib/Support/Windows/Threading.inc Thu Oct 30 17:07:09 2014
> @@ -0,0 +1,19 @@
> +#include <winbase.h>
> +
> +void llvm::call_once(once_flag &flag, void (*fptr)(void)) {
> +  while (flag != Done) {
> +    if (flag == Wait) {
> +      ::Sleep(1);
> +      continue;
> +    }
> +
> +    sys::cas_flag old_val = sys::CompareAndSwap(&flag, Wait, Uninitialized);
> +    if (old_val == Uninitialized) {
> +      fptr();
> +      sys::MemoryFence();
> +      flag = Done;
> +      return;
> +    }
> +  }
> +  sys::MemoryFence();
> +}
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu <mailto:llvm-commits at cs.uiuc.edu>
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits <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/20141104/4697d1a7/attachment.html>


More information about the llvm-commits mailing list