Split the thread-related APIs out into their own file, and add a few more
calls for convenience.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73512 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Support/ManagedStatic.cpp b/lib/Support/ManagedStatic.cpp
index 6de6575..4e655a0 100644
--- a/lib/Support/ManagedStatic.cpp
+++ b/lib/Support/ManagedStatic.cpp
@@ -14,18 +14,15 @@
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Config/config.h"
 #include "llvm/System/Atomic.h"
-#include "llvm/System/Mutex.h"
 #include <cassert>
 using namespace llvm;
 
 static const ManagedStaticBase *StaticList = 0;
 
-static sys::Mutex* ManagedStaticMutex = 0;
-
 void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
                                               void (*Deleter)(void*)) const {
-  if (ManagedStaticMutex) {
-    ManagedStaticMutex->acquire();
+  if (llvm_is_multithreaded()) {
+    llvm_acquire_global_lock();
 
     if (Ptr == 0) {
       void* tmp = Creator ? Creator() : 0;
@@ -39,7 +36,7 @@
       StaticList = this;
     }
 
-    ManagedStaticMutex->release();
+    llvm_release_global_lock();
   } else {
     assert(Ptr == 0 && DeleterFn == 0 && Next == 0 &&
            "Partially initialized ManagedStatic!?");
@@ -68,24 +65,11 @@
   DeleterFn = 0;
 }
 
-bool llvm::llvm_start_multithreaded() {
-#if LLVM_MULTITHREADED
-  assert(ManagedStaticMutex == 0 && "Multithreaded LLVM already initialized!");
-  ManagedStaticMutex = new sys::Mutex(true);
-  return true;
-#else
-  return false;
-#endif
-}
-
 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
 void llvm::llvm_shutdown() {
   while (StaticList)
     StaticList->destroy();
 
-  if (ManagedStaticMutex) {
-    delete ManagedStaticMutex;
-    ManagedStaticMutex = 0;
-  }
+  if (llvm_is_multithreaded()) llvm_stop_multithreaded();
 }
 
diff --git a/lib/Support/Threading.cpp b/lib/Support/Threading.cpp
new file mode 100644
index 0000000..a587648
--- /dev/null
+++ b/lib/Support/Threading.cpp
@@ -0,0 +1,63 @@
+//===-- llvm/Support/Threading.cpp- Control multithreading mode --*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements llvm_start_multithreaded() and friends.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Threading.h"
+#include "llvm/System/Atomic.h"
+#include "llvm/System/Mutex.h"
+#include <cassert>
+
+using namespace llvm;
+
+static bool multithreaded_mode = false;
+
+static sys::Mutex* global_lock = 0;
+
+bool llvm::llvm_start_multithreaded() {
+#ifdef LLVM_MULTITHREADED
+  assert(!multithreaded_mode && "Already multithreaded!");
+  multithreaded_mode = true;
+  global_lock = new sys::Mutex(true);
+  
+  // We fence here to ensure that all initialization is complete BEFORE we
+  // return from llvm_start_multithreaded().
+  sys::MemoryFence();
+  return true;
+#else
+  return false;
+#endif
+}
+
+void llvm::llvm_stop_multithreaded() {
+#ifdef LLVM_MULTITHREADED
+  assert(multithreaded_mode && "Not currently multithreaded!");
+  
+  // We fence here to insure that all threaded operations are complete BEFORE we
+  // return from llvm_stop_multithreaded().
+  sys::MemoryFence();
+  
+  multithreaded_mode = false;
+  delete global_lock;
+#endif
+}
+
+bool llvm::llvm_is_multithreaded() {
+  return multithreaded_mode;
+}
+
+void llvm::llvm_acquire_global_lock() {
+  if (multithreaded_mode) global_lock->acquire();
+}
+
+void llvm::llvm_release_global_lock() {
+  if (multithreaded_mode) global_lock->release();
+}
\ No newline at end of file