Remove support for runtime multi-threading.
authorZachary Turner <zturner@google.com>
Tue, 10 Jun 2014 23:01:20 +0000 (23:01 +0000)
committerZachary Turner <zturner@google.com>
Tue, 10 Jun 2014 23:01:20 +0000 (23:01 +0000)
This patch removes the functions llvm_start_multithreaded() and
llvm_stop_multithreaded(), and changes llvm_is_multithreaded()
to return a constant value based on the value of the compile-time
definition LLVM_ENABLE_THREADS.

Previously, it was possible to have compile-time support for
threads on, and runtime support for threads off, in which case
certain mutexes were not allocated or ever acquired.  Now, if the
build is created with threads enabled, mutexes are always acquired.

A test before/after patch of compiling a very large TU showed no
noticeable performance impact of this change.

Reviewers: rnk

Differential Revision: http://reviews.llvm.org/D4076

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210600 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm-c/Core.h
include/llvm/Support/ManagedStatic.h
include/llvm/Support/Threading.h
lib/IR/Core.cpp
lib/Support/ErrorHandling.cpp
lib/Support/ManagedStatic.cpp
lib/Support/Threading.cpp
lib/Support/Timer.cpp

index 0e78ed71fa9afaf7593a2205c0db3fdc993a2af4..8693a3020aba346c811dca559662d4bf2aa6aacb 100644 (file)
@@ -2848,16 +2848,13 @@ void LLVMDisposePassManager(LLVMPassManagerRef PM);
  * @{
  */
 
  * @{
  */
 
-/** Allocate and initialize structures needed to make LLVM safe for
-    multithreading. The return value indicates whether multithreaded
-    initialization succeeded. Must be executed in isolation from all
-    other LLVM api calls.
-    @see llvm::llvm_start_multithreaded */
+/** Deprecated: Multi-threading can only be enabled/disabled with the compile
+    time define LLVM_ENABLE_THREADS.  This function always returns
+    LLVMIsMultithreaded(). */
 LLVMBool LLVMStartMultithreaded(void);
 
 LLVMBool LLVMStartMultithreaded(void);
 
-/** Deallocate structures necessary to make LLVM safe for multithreading.
-    Must be executed in isolation from all other LLVM api calls.
-    @see llvm::llvm_stop_multithreaded */
+/** Deprecated: Multi-threading can only be enabled/disabled with the compile
+    time define LLVM_ENABLE_THREADS. */
 void LLVMStopMultithreaded(void);
 
 /** Check whether LLVM is executing in thread-safe mode or not.
 void LLVMStopMultithreaded(void);
 
 /** Check whether LLVM is executing in thread-safe mode or not.
index 1bb8cea092f9b693f14f5f840d4b4be80f637c4d..d8fbfeb8e20cee089f8985d1ff9aa70a2a4515ca 100644 (file)
@@ -103,9 +103,6 @@ void llvm_shutdown();
 /// llvm_shutdown() when it is destroyed.
 struct llvm_shutdown_obj {
   llvm_shutdown_obj() { }
 /// llvm_shutdown() when it is destroyed.
 struct llvm_shutdown_obj {
   llvm_shutdown_obj() { }
-  explicit llvm_shutdown_obj(bool multithreaded) {
-    if (multithreaded) llvm_start_multithreaded();
-  }
   ~llvm_shutdown_obj() { llvm_shutdown(); }
 };
 
   ~llvm_shutdown_obj() { llvm_shutdown(); }
 };
 
index a7e8774558d5886e4462e74e014a569baf7481bb..75b6ddbfda200c984dbc73f572f750134c51abc5 100644 (file)
 #ifndef LLVM_SUPPORT_THREADING_H
 #define LLVM_SUPPORT_THREADING_H
 
 #ifndef LLVM_SUPPORT_THREADING_H
 #define LLVM_SUPPORT_THREADING_H
 
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/Compiler.h"
+#include <mutex>
+
 namespace llvm {
 namespace llvm {
-  /// llvm_start_multithreaded - Allocate and initialize structures needed to
-  /// make LLVM safe for multithreading.  The return value indicates whether
-  /// multithreaded initialization succeeded.  LLVM will still be operational
-  /// on "failed" return, and will still be safe for hosting threading
-  /// applications in the JIT, but will not be safe for concurrent calls to the
-  /// LLVM APIs.
-  /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
-  bool llvm_start_multithreaded();
-
-  /// llvm_stop_multithreaded - Deallocate structures necessary to make LLVM
-  /// safe for multithreading.
-  /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
-  void llvm_stop_multithreaded();
-
-  /// llvm_is_multithreaded - Check whether LLVM is executing in thread-safe
-  /// mode or not.
-  bool llvm_is_multithreaded();
 
 
-  /// acquire_global_lock - Acquire the global lock.  This is a no-op if called
-  /// before llvm_start_multithreaded().
-  void llvm_acquire_global_lock();
+#if LLVM_ENABLE_THREADS != 0
+  typedef std::mutex mutex;
+  typedef std::recursive_mutex recursive_mutex;
+#else
+  class null_mutex {
+  public:
+    void lock() { }
+    void unlock() { }
+    bool try_lock() { return true; }
+  };
+  typedef null_mutex mutex;
+  typedef null_mutex recursive_mutex;
+#endif
 
 
-  /// release_global_lock - Release the global lock.  This is a no-op if called
-  /// before llvm_start_multithreaded().
-  void llvm_release_global_lock();
+  /// llvm_get_global_lock() - returns the llvm global lock object.
+  llvm::recursive_mutex &llvm_get_global_lock();
+
+  /// llvm_is_multithreaded() - returns true if LLVM is compiled with support
+  /// for multiple threads, and false otherwise.
+  bool llvm_is_multithreaded();
 
   /// llvm_execute_on_thread - Execute the given \p UserFn on a separate
   /// thread, passing it the provided \p UserData.
 
   /// llvm_execute_on_thread - Execute the given \p UserFn on a separate
   /// thread, passing it the provided \p UserData.
index f24704c61cd833e6e726060b4fdeda4a7d2de137..2bdc92da8fc5e102d5907a440284220b689e7172 100644 (file)
@@ -2702,11 +2702,10 @@ void LLVMDisposePassManager(LLVMPassManagerRef PM) {
 /*===-- Threading ------------------------------------------------------===*/
 
 LLVMBool LLVMStartMultithreaded() {
 /*===-- Threading ------------------------------------------------------===*/
 
 LLVMBool LLVMStartMultithreaded() {
-  return llvm_start_multithreaded();
+  return LLVMIsMultithreaded();
 }
 
 void LLVMStopMultithreaded() {
 }
 
 void LLVMStopMultithreaded() {
-  llvm_stop_multithreaded();
 }
 
 LLVMBool LLVMIsMultithreaded() {
 }
 
 LLVMBool LLVMIsMultithreaded() {
index 342c4f05cc9da03ea50c9e63649565dc3f8632a9..b9e4eabe926a63fd83dd9504e6ab8e624ae90024 100644 (file)
@@ -23,6 +23,7 @@
 #include "llvm/Support/raw_ostream.h"
 #include <cassert>
 #include <cstdlib>
 #include "llvm/Support/raw_ostream.h"
 #include <cassert>
 #include <cstdlib>
+#include <mutex>
 
 #if defined(HAVE_UNISTD_H)
 # include <unistd.h>
 
 #if defined(HAVE_UNISTD_H)
 # include <unistd.h>
@@ -37,16 +38,18 @@ using namespace llvm;
 static fatal_error_handler_t ErrorHandler = nullptr;
 static void *ErrorHandlerUserData = nullptr;
 
 static fatal_error_handler_t ErrorHandler = nullptr;
 static void *ErrorHandlerUserData = nullptr;
 
+static llvm::recursive_mutex ErrorHandlerMutex;
+
 void llvm::install_fatal_error_handler(fatal_error_handler_t handler,
                                        void *user_data) {
 void llvm::install_fatal_error_handler(fatal_error_handler_t handler,
                                        void *user_data) {
-  assert(!llvm_is_multithreaded() &&
-         "Cannot register error handlers after starting multithreaded mode!\n");
+  std::lock_guard<llvm::recursive_mutex> Lock(ErrorHandlerMutex);
   assert(!ErrorHandler && "Error handler already registered!\n");
   ErrorHandler = handler;
   ErrorHandlerUserData = user_data;
 }
 
 void llvm::remove_fatal_error_handler() {
   assert(!ErrorHandler && "Error handler already registered!\n");
   ErrorHandler = handler;
   ErrorHandlerUserData = user_data;
 }
 
 void llvm::remove_fatal_error_handler() {
+  std::lock_guard<llvm::recursive_mutex> Lock(ErrorHandlerMutex);
   ErrorHandler = nullptr;
 }
 
   ErrorHandler = nullptr;
 }
 
@@ -63,6 +66,7 @@ void llvm::report_fatal_error(StringRef Reason, bool GenCrashDiag) {
 }
 
 void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) {
 }
 
 void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) {
+  std::lock_guard<llvm::recursive_mutex> Lock(ErrorHandlerMutex);
   if (ErrorHandler) {
     ErrorHandler(ErrorHandlerUserData, Reason.str(), GenCrashDiag);
   } else {
   if (ErrorHandler) {
     ErrorHandler(ErrorHandlerUserData, Reason.str(), GenCrashDiag);
   } else {
index 6a1c2a545a8d87f2a59ffed59c0542aa30caf32b..74884d9330491401359c8916a2787e2065130179 100644 (file)
@@ -15,6 +15,7 @@
 #include "llvm/Config/config.h"
 #include "llvm/Support/Atomic.h"
 #include <cassert>
 #include "llvm/Config/config.h"
 #include "llvm/Support/Atomic.h"
 #include <cassert>
+#include <mutex>
 using namespace llvm;
 
 static const ManagedStaticBase *StaticList = nullptr;
 using namespace llvm;
 
 static const ManagedStaticBase *StaticList = nullptr;
@@ -23,7 +24,7 @@ void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
                                               void (*Deleter)(void*)) const {
   assert(Creator);
   if (llvm_is_multithreaded()) {
                                               void (*Deleter)(void*)) const {
   assert(Creator);
   if (llvm_is_multithreaded()) {
-    llvm_acquire_global_lock();
+    std::lock_guard<llvm::recursive_mutex> Lock(llvm_get_global_lock());
 
     if (!Ptr) {
       void* tmp = Creator();
 
     if (!Ptr) {
       void* tmp = Creator();
@@ -44,7 +45,6 @@ void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
       StaticList = this;
     }
 
       StaticList = this;
     }
 
-    llvm_release_global_lock();
   } else {
     assert(!Ptr && !DeleterFn && !Next &&
            "Partially initialized ManagedStatic!?");
   } else {
     assert(!Ptr && !DeleterFn && !Next &&
            "Partially initialized ManagedStatic!?");
@@ -77,6 +77,4 @@ void ManagedStaticBase::destroy() const {
 void llvm::llvm_shutdown() {
   while (StaticList)
     StaticList->destroy();
 void llvm::llvm_shutdown() {
   while (StaticList)
     StaticList->destroy();
-
-  if (llvm_is_multithreaded()) llvm_stop_multithreaded();
 }
 }
index 1acfa79b11d5835f60103057e16f4b5f377d6f39..c9f0f2c2e5a20493bbb97a927172971c6bac9d43 100644 (file)
 
 using namespace llvm;
 
 
 using namespace llvm;
 
-static bool multithreaded_mode = false;
-
-static sys::Mutex* global_lock = nullptr;
+llvm::recursive_mutex& llvm::llvm_get_global_lock() {
+  static llvm::recursive_mutex global_lock;
+  return global_lock;
+}
 
 
-bool llvm::llvm_start_multithreaded() {
+bool llvm::llvm_is_multithreaded() {
 #if LLVM_ENABLE_THREADS != 0
 #if LLVM_ENABLE_THREADS != 0
-  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
 }
 
   return true;
 #else
   return false;
 #endif
 }
 
-void llvm::llvm_stop_multithreaded() {
-#if LLVM_ENABLE_THREADS != 0
-  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();
-}
-
 #if LLVM_ENABLE_THREADS != 0 && defined(HAVE_PTHREAD_H)
 #include <pthread.h>
 
 #if LLVM_ENABLE_THREADS != 0 && defined(HAVE_PTHREAD_H)
 #include <pthread.h>
 
index 61465ae5e8be861a33d12058c38fa9c11cf50b9d..cdab02b2fb778945625cc08969189adf73ba7b89 100644 (file)
@@ -84,14 +84,13 @@ static TimerGroup *getDefaultTimerGroup() {
   sys::MemoryFence();
   if (tmp) return tmp;
   
   sys::MemoryFence();
   if (tmp) return tmp;
   
-  llvm_acquire_global_lock();
+  std::lock_guard<llvm::recursive_mutex> Lock(llvm::llvm_get_global_lock());
   tmp = DefaultTimerGroup;
   if (!tmp) {
     tmp = new TimerGroup("Miscellaneous Ungrouped Timers");
     sys::MemoryFence();
     DefaultTimerGroup = tmp;
   }
   tmp = DefaultTimerGroup;
   if (!tmp) {
     tmp = new TimerGroup("Miscellaneous Ungrouped Timers");
     sys::MemoryFence();
     DefaultTimerGroup = tmp;
   }
-  llvm_release_global_lock();
 
   return tmp;
 }
 
   return tmp;
 }