<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">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.<div class=""><br class=""></div><div class="">-Chris</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Nov 4, 2014, at 12:12 AM, Jiangning Liu <<a href="mailto:liujiangning1@gmail.com" class="">liujiangning1@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">BTW, my OS is debian and "uname -a" shows,<div class=""><br class=""></div><div class="">Linux 3.15.0-rc8+ #9 SMP PREEMPT aarch64 GNU/Linux<br class=""></div><div class=""><br class=""></div><div class="">Thanks,</div><div class="">-Jiangning</div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">2014-11-04 16:09 GMT+08:00 Jiangning Liu <span dir="ltr" class=""><<a href="mailto:liujiangning1@gmail.com" target="_blank" class="">liujiangning1@gmail.com</a>></span>:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="">Hi Chris,<br class=""><br class="">This commit triggered a llvm/clang build failure on aarch64 host machine. The error message is like,<br class=""><br class="">/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/<a href="http://arm_neon.td/" target="_blank" class="">arm_neon.td</a> -o /work/slave/performance-daily/build/build/tools/clang/lib/Headers/arm_neon.h.tmp<br class=""><br class="">It seems pthread doesn't work well on aarch64 target, so the following code doesn't work.<span class=""><br class=""><br class="">+void llvm::call_once(once_flag& flag, void (*fptr)(void)) {<br class="">+  std::call_once(flag, fptr);<br class="">+}<br class=""><br class=""></span>Can we use the same solution as windows rather than call std::call_once directly?<br class=""><br class="">Thanks,<br class="">-Jiangning<div class=""><div class=""><span style="color:red;font-family:'Courier New',courier,monotype,monospace;white-space:pre-wrap" class=""><br class=""></span></div></div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br class=""><div class="gmail_quote">2014-10-31 6:07 GMT+08:00 Chris Bieneman <span dir="ltr" class=""><<a href="mailto:beanz@apple.com" target="_blank" class="">beanz@apple.com</a>></span>:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: cbieneman<br class="">
Date: Thu Oct 30 17:07:09 2014<br class="">
New Revision: 220932<br class="">
<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=220932&view=rev" target="_blank" class="">http://llvm.org/viewvc/llvm-project?rev=220932&view=rev</a><br class="">
Log:<br class="">
Removing the static initializer in ManagedStatic.cpp by using llvm_call_once to initialize the ManagedStatic mutex.<br class="">
<br class="">
Summary:<br class="">
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.<br class="">
<br class="">
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.<br class="">
<br class="">
Reviewers: aaron.ballman, chapuni, chandlerc, rnk<br class="">
<br class="">
Reviewed By: rnk<br class="">
<br class="">
Subscribers: majnemer, llvm-commits<br class="">
<br class="">
Differential Revision: <a href="http://reviews.llvm.org/D5922" target="_blank" class="">http://reviews.llvm.org/D5922</a><br class="">
<br class="">
Added:<br class="">
    llvm/trunk/lib/Support/Unix/Threading.inc<br class="">
    llvm/trunk/lib/Support/Windows/Threading.inc<br class="">
Modified:<br class="">
    llvm/trunk/include/llvm/Support/Threading.h<br class="">
    llvm/trunk/lib/Support/CMakeLists.txt<br class="">
    llvm/trunk/lib/Support/ManagedStatic.cpp<br class="">
    llvm/trunk/lib/Support/Threading.cpp<br class="">
<br class="">
Modified: llvm/trunk/include/llvm/Support/Threading.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Threading.h?rev=220932&r1=220931&r2=220932&view=diff" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Threading.h?rev=220932&r1=220931&r2=220932&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/include/llvm/Support/Threading.h (original)<br class="">
+++ llvm/trunk/include/llvm/Support/Threading.h Thu Oct 30 17:07:09 2014<br class="">
@@ -15,6 +15,14 @@<br class="">
 #ifndef LLVM_SUPPORT_THREADING_H<br class="">
 #define LLVM_SUPPORT_THREADING_H<br class="">
<br class="">
+#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX<br class="">
+<br class="">
+#if defined(LLVM_ON_UNIX)<br class="">
+#include <mutex><br class="">
+#else<br class="">
+#include "llvm/Support/Atomic.h"<br class="">
+#endif<br class="">
+<br class="">
 namespace llvm {<br class="">
   /// Returns true if LLVM is compiled with support for multi-threading, and<br class="">
   /// false otherwise.<br class="">
@@ -33,6 +41,35 @@ namespace llvm {<br class="">
   /// the thread stack.<br class="">
   void llvm_execute_on_thread(void (*UserFn)(void*), void *UserData,<br class="">
                               unsigned RequestedStackSize = 0);<br class="">
+<br class="">
+#if defined(LLVM_ON_UNIX)<br class="">
+typedef std::once_flag once_flag;<br class="">
+#define LLVM_DEFINE_ONCE_FLAG(flag) static once_flag flag<br class="">
+#else<br class="">
+enum InitStatus {<br class="">
+  Done = -1,<br class="">
+  Uninitialized = 0,<br class="">
+  Wait = 1<br class="">
+};<br class="">
+typedef volatile sys::cas_flag once_flag;<br class="">
+<br class="">
+#define LLVM_DEFINE_ONCE_FLAG(flag) static once_flag flag = Uninitialized<br class="">
+#endif<br class="">
+<br class="">
+/// \brief Execute the function specified as a parameter once.<br class="">
+///<br class="">
+/// Typical usage:<br class="">
+/// \code<br class="">
+///   void foo() {...};<br class="">
+///   ...<br class="">
+///   LLVM_DEFINE_ONCE_FLAG(flag);<br class="">
+///   call_once(flag, foo);<br class="">
+/// \endcode<br class="">
+///<br class="">
+/// \param flag Flag used for tracking whether or not this has run.<br class="">
+/// \param UserFn Function to call once.<br class="">
+void call_once(once_flag&, void (*)(void));<br class="">
+<br class="">
 }<br class="">
<br class="">
 #endif<br class="">
<br class="">
Modified: llvm/trunk/lib/Support/CMakeLists.txt<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CMakeLists.txt?rev=220932&r1=220931&r2=220932&view=diff" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CMakeLists.txt?rev=220932&r1=220931&r2=220932&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Support/CMakeLists.txt (original)<br class="">
+++ llvm/trunk/lib/Support/CMakeLists.txt Thu Oct 30 17:07:09 2014<br class="">
@@ -102,6 +102,7 @@ add_llvm_library(LLVMSupport<br class="">
   Unix/Program.inc<br class="">
   Unix/RWMutex.inc<br class="">
   Unix/Signals.inc<br class="">
+  Unix/Threading.inc<br class="">
   Unix/ThreadLocal.inc<br class="">
   Unix/TimeValue.inc<br class="">
   Unix/Watchdog.inc<br class="">
@@ -114,6 +115,7 @@ add_llvm_library(LLVMSupport<br class="">
   Windows/Program.inc<br class="">
   Windows/RWMutex.inc<br class="">
   Windows/Signals.inc<br class="">
+  Windows/Threading.inc<br class="">
   Windows/ThreadLocal.inc<br class="">
   Windows/TimeValue.inc<br class="">
   Windows/Watchdog.inc<br class="">
<br class="">
Modified: llvm/trunk/lib/Support/ManagedStatic.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/ManagedStatic.cpp?rev=220932&r1=220931&r2=220932&view=diff" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/ManagedStatic.cpp?rev=220932&r1=220931&r2=220932&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Support/ManagedStatic.cpp (original)<br class="">
+++ llvm/trunk/lib/Support/ManagedStatic.cpp Thu Oct 30 17:07:09 2014<br class="">
@@ -16,16 +16,23 @@<br class="">
 #include "llvm/Support/Atomic.h"<br class="">
 #include "llvm/Support/Mutex.h"<br class="">
 #include "llvm/Support/MutexGuard.h"<br class="">
+#include "llvm/Support/Threading.h"<br class="">
 #include <cassert><br class="">
 using namespace llvm;<br class="">
<br class="">
 static const ManagedStaticBase *StaticList = nullptr;<br class="">
+static sys::Mutex *ManagedStaticMutex = nullptr;<br class="">
+LLVM_DEFINE_ONCE_FLAG(mutex_init_flag);<br class="">
<br class="">
-static sys::Mutex& getManagedStaticMutex() {<br class="">
+static void initializeMutex() {<br class="">
+  ManagedStaticMutex = new sys::Mutex();<br class="">
+}<br class="">
+<br class="">
+static sys::Mutex* getManagedStaticMutex() {<br class="">
   // We need to use a function local static here, since this can get called<br class="">
   // during a static constructor and we need to guarantee that it's initialized<br class="">
   // correctly.<br class="">
-  static sys::Mutex ManagedStaticMutex;<br class="">
+  call_once(mutex_init_flag, initializeMutex);<br class="">
   return ManagedStaticMutex;<br class="">
 }<br class="">
<br class="">
@@ -33,7 +40,7 @@ void ManagedStaticBase::RegisterManagedS<br class="">
                                               void (*Deleter)(void*)) const {<br class="">
   assert(Creator);<br class="">
   if (llvm_is_multithreaded()) {<br class="">
-    MutexGuard Lock(getManagedStaticMutex());<br class="">
+    MutexGuard Lock(*getManagedStaticMutex());<br class="">
<br class="">
     if (!Ptr) {<br class="">
       void* tmp = Creator();<br class="">
@@ -83,7 +90,7 @@ void ManagedStaticBase::destroy() const<br class="">
<br class="">
 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.<br class="">
 void llvm::llvm_shutdown() {<br class="">
-  MutexGuard Lock(getManagedStaticMutex());<br class="">
+  MutexGuard Lock(*getManagedStaticMutex());<br class="">
<br class="">
   while (StaticList)<br class="">
     StaticList->destroy();<br class="">
<br class="">
Modified: llvm/trunk/lib/Support/Threading.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Threading.cpp?rev=220932&r1=220931&r2=220932&view=diff" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Threading.cpp?rev=220932&r1=220931&r2=220932&view=diff</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Support/Threading.cpp (original)<br class="">
+++ llvm/trunk/lib/Support/Threading.cpp Thu Oct 30 17:07:09 2014<br class="">
@@ -110,3 +110,10 @@ void llvm::llvm_execute_on_thread(void (<br class="">
 }<br class="">
<br class="">
 #endif<br class="">
+<br class="">
+#if defined(LLVM_ON_UNIX)<br class="">
+#include "Unix/Threading.inc"<br class="">
+#else<br class="">
+#include "Windows/Threading.inc"<br class="">
+#endif<br class="">
+<br class="">
<br class="">
Added: llvm/trunk/lib/Support/Unix/Threading.inc<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Threading.inc?rev=220932&view=auto" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Threading.inc?rev=220932&view=auto</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Support/Unix/Threading.inc (added)<br class="">
+++ llvm/trunk/lib/Support/Unix/Threading.inc Thu Oct 30 17:07:09 2014<br class="">
@@ -0,0 +1,5 @@<br class="">
+#include <thread><br class="">
+<br class="">
+void llvm::call_once(once_flag& flag, void (*fptr)(void)) {<br class="">
+  std::call_once(flag, fptr);<br class="">
+}<br class="">
<br class="">
Added: llvm/trunk/lib/Support/Windows/Threading.inc<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Threading.inc?rev=220932&view=auto" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Threading.inc?rev=220932&view=auto</a><br class="">
==============================================================================<br class="">
--- llvm/trunk/lib/Support/Windows/Threading.inc (added)<br class="">
+++ llvm/trunk/lib/Support/Windows/Threading.inc Thu Oct 30 17:07:09 2014<br class="">
@@ -0,0 +1,19 @@<br class="">
+#include <winbase.h><br class="">
+<br class="">
+void llvm::call_once(once_flag &flag, void (*fptr)(void)) {<br class="">
+  while (flag != Done) {<br class="">
+    if (flag == Wait) {<br class="">
+      ::Sleep(1);<br class="">
+      continue;<br class="">
+    }<br class="">
+<br class="">
+    sys::cas_flag old_val = sys::CompareAndSwap(&flag, Wait, Uninitialized);<br class="">
+    if (old_val == Uninitialized) {<br class="">
+      fptr();<br class="">
+      sys::MemoryFence();<br class="">
+      flag = Done;<br class="">
+      return;<br class="">
+    }<br class="">
+  }<br class="">
+  sys::MemoryFence();<br class="">
+}<br class="">
<br class="">
<br class="">
_______________________________________________<br class="">
llvm-commits mailing list<br class="">
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank" class="">llvm-commits@cs.uiuc.edu</a><br class="">
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank" class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br class="">
</blockquote></div><br class=""></div>
</div></div></blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></div></body></html>