<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>