llvm.org GIT mirror llvm / 5ea4669
Revert r211066, 211067, 211068, 211069, 211070. These were committed accidentally from the wrong branch before having a review sign-off. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211072 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 5 years ago
10 changed file(s) with 134 addition(s) and 47 deletion(s). Raw diff Collapse all Expand all
21692169 using the resultant compiler to build a copy of LLVM with multithreading
21702170 support.
21712171
2172 .. _startmultithreaded:
2173
2174 Entering and Exiting Multithreaded Mode
2175 ---------------------------------------
2176
2177 In order to properly protect its internal data structures while avoiding
2178 excessive locking overhead in the single-threaded case, the LLVM must intialize
2179 certain data structures necessary to provide guards around its internals. To do
2180 so, the client program must invoke ``llvm_start_multithreaded()`` before making
2181 any concurrent LLVM API calls. To subsequently tear down these structures, use
2182 the ``llvm_stop_multithreaded()`` call. You can also use the
2183 ``llvm_is_multithreaded()`` call to check the status of multithreaded mode.
2184
2185 Note that both of these calls must be made *in isolation*. That is to say that
2186 no other LLVM API calls may be executing at any time during the execution of
2187 ``llvm_start_multithreaded()`` or ``llvm_stop_multithreaded``. It is the
2188 client's responsibility to enforce this isolation.
2189
2190 The return value of ``llvm_start_multithreaded()`` indicates the success or
2191 failure of the initialization. Failure typically indicates that your copy of
2192 LLVM was built without multithreading support, typically because GCC atomic
2193 intrinsics were not found in your system compiler. In this case, the LLVM API
2194 will not be safe for concurrent calls. However, it *will* be safe for hosting
2195 threaded applications in the JIT, though :ref:`care must be taken
2196 ` to ensure that side exits and the like do not accidentally
2197 result in concurrent LLVM API calls.
2198
21722199 .. _shutdown:
21732200
21742201 Ending Execution with ``llvm_shutdown()``
21752202 -----------------------------------------
21762203
21772204 When you are done using the LLVM APIs, you should call ``llvm_shutdown()`` to
2178 deallocate memory used for internal structures.
2205 deallocate memory used for internal structures. This will also invoke
2206 ``llvm_stop_multithreaded()`` if LLVM is operating in multithreaded mode. As
2207 such, ``llvm_shutdown()`` requires the same isolation guarantees as
2208 ``llvm_stop_multithreaded()``.
2209
2210 Note that, if you use scope-based shutdown, you can use the
2211 ``llvm_shutdown_obj`` class, which calls ``llvm_shutdown()`` in its destructor.
2212
21792213 .. _managedstatic:
21802214
21812215 Lazy Initialization with ``ManagedStatic``
21822216 ------------------------------------------
21832217
21842218 ``ManagedStatic`` is a utility class in LLVM used to implement static
2185 initialization of static resources, such as the global type tables. In a
2186 single-threaded environment, it implements a simple lazy initialization scheme.
2187 When LLVM is compiled with support for multi-threading, however, it uses
2219 initialization of static resources, such as the global type tables. Before the
2220 invocation of ``llvm_shutdown()``, it implements a simple lazy initialization
2221 scheme. Once ``llvm_start_multithreaded()`` returns, however, it uses
21882222 double-checked locking to implement thread-safe lazy initialization.
2223
2224 Note that, because no other threads are allowed to issue LLVM API calls before
2225 ``llvm_start_multithreaded()`` returns, it is possible to have
2226 ``ManagedStatic``\ s of ``llvm::sys::Mutex``\ s.
2227
2228 The ``llvm_acquire_global_lock()`` and ``llvm_release_global_lock`` APIs provide
2229 access to the global lock used to implement the double-checked locking for lazy
2230 initialization. These should only be used internally to LLVM, and only if you
2231 know what you're doing!
21892232
21902233 .. _llvmcontext:
21912234
102102 /// llvm_shutdown() when it is destroyed.
103103 struct llvm_shutdown_obj {
104104 llvm_shutdown_obj() { }
105 explicit llvm_shutdown_obj(bool multithreaded) {
106 if (multithreaded) llvm_start_multithreaded();
107 }
105108 ~llvm_shutdown_obj() { llvm_shutdown(); }
106109 };
107110
1414 #define LLVM_SUPPORT_MUTEX_H
1515
1616 #include "llvm/Support/Compiler.h"
17 #include "llvm/Support/Threading.h"
1718 #include
1819
1920 namespace llvm
2021 {
21 // Forward declare.
22 bool llvm_is_multithreaded();
23
2422 namespace sys
2523 {
2624 /// @brief Platform agnostic Mutex class.
66 //
77 //===----------------------------------------------------------------------===//
88 //
9 // This file defines helper functions for running LLVM in a multi-threaded
10 // environment.
9 // TThis file defines llvm_start_multithreaded() and friends.
1110 //
1211 //===----------------------------------------------------------------------===//
1312
1413 #ifndef LLVM_SUPPORT_THREADING_H
1514 #define LLVM_SUPPORT_THREADING_H
1615
17 #include "llvm/Support/Mutex.h"
16 namespace llvm {
17 /// llvm_start_multithreaded - Allocate and initialize structures needed to
18 /// make LLVM safe for multithreading. The return value indicates whether
19 /// multithreaded initialization succeeded. LLVM will still be operational
20 /// on "failed" return, and will still be safe for hosting threading
21 /// applications in the JIT, but will not be safe for concurrent calls to the
22 /// LLVM APIs.
23 /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
24 bool llvm_start_multithreaded();
1825
19 namespace llvm {
20 /// llvm_is_multithreaded - returns true if LLVM is compiled with support
21 /// for multiple threads, and false otherwise.
26 /// llvm_stop_multithreaded - Deallocate structures necessary to make LLVM
27 /// safe for multithreading.
28 /// THIS MUST EXECUTE IN ISOLATION FROM ALL OTHER LLVM API CALLS.
29 void llvm_stop_multithreaded();
30
31 /// llvm_is_multithreaded - Check whether LLVM is executing in thread-safe
32 /// mode or not.
2233 bool llvm_is_multithreaded();
34
35 /// acquire_global_lock - Acquire the global lock. This is a no-op if called
36 /// before llvm_start_multithreaded().
37 void llvm_acquire_global_lock();
38
39 /// release_global_lock - Release the global lock. This is a no-op if called
40 /// before llvm_start_multithreaded().
41 void llvm_release_global_lock();
2342
2443 /// llvm_execute_on_thread - Execute the given \p UserFn on a separate
2544 /// thread, passing it the provided \p UserData.
28472847 * @{
28482848 */
28492849
2850 /** Deprecated: Multi-threading can only be enabled/disabled with the compile
2851 time define LLVM_ENABLE_THREADS. This function always returns
2852 LLVMIsMultithreaded(). */
2850 /** Allocate and initialize structures needed to make LLVM safe for
2851 multithreading. The return value indicates whether multithreaded
2852 initialization succeeded. Must be executed in isolation from all
2853 other LLVM api calls.
2854 @see llvm::llvm_start_multithreaded */
28532855 LLVMBool LLVMStartMultithreaded(void);
28542856
2855 /** Deprecated: Multi-threading can only be enabled/disabled with the compile
2856 time define LLVM_ENABLE_THREADS. */
2857 /** Deallocate structures necessary to make LLVM safe for multithreading.
2858 Must be executed in isolation from all other LLVM api calls.
2859 @see llvm::llvm_stop_multithreaded */
28572860 void LLVMStopMultithreaded(void);
28582861
28592862 /** Check whether LLVM is executing in thread-safe mode or not.
27012701 /*===-- Threading ------------------------------------------------------===*/
27022702
27032703 LLVMBool LLVMStartMultithreaded() {
2704 return LLVMIsMultithreaded();
2704 return llvm_start_multithreaded();
27052705 }
27062706
27072707 void LLVMStopMultithreaded() {
2708 llvm_stop_multithreaded();
27082709 }
27092710
27102711 LLVMBool LLVMIsMultithreaded() {
1313 #include "llvm/Support/ManagedStatic.h"
1414 #include "llvm/Config/config.h"
1515 #include "llvm/Support/Atomic.h"
16 #include "llvm/Support/MutexGuard.h"
1716 #include
18 #include
1917 using namespace llvm;
2018
2119 static const ManagedStaticBase *StaticList = nullptr;
22
23 // ManagedStatics can get created during execution of static constructors. As a
24 // result, we cannot use a global static std::mutex object for the lock since it
25 // may not have been constructed. Instead, we do a call-once initialization of
26 // a pointer to a mutex. This also means that we must not "initialize" the
27 // mutex with nullptr, otherwise it might get reset to nullptr after being
28 // initialized by std::call_once.
29 static std::once_flag MutexInitializationFlag;
30 static std::recursive_mutex *ManagedStaticMutex;
31
32 namespace {
33 void InitializeManagedStaticMutex() {
34 std::call_once(MutexInitializationFlag,
35 []() { ManagedStaticMutex = new std::recursive_mutex(); });
36 }
37 }
3820
3921 void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
4022 void (*Deleter)(void*)) const {
4123 assert(Creator);
4224 if (llvm_is_multithreaded()) {
43 InitializeManagedStaticMutex();
25 llvm_acquire_global_lock();
4426
45 std::lock_guard Lock(*ManagedStaticMutex);
4627 if (!Ptr) {
4728 void* tmp = Creator();
4829
6142 Next = StaticList;
6243 StaticList = this;
6344 }
45
46 llvm_release_global_lock();
6447 } else {
6548 assert(!Ptr && !DeleterFn && !Next &&
6649 "Partially initialized ManagedStatic!?");
9174
9275 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
9376 void llvm::llvm_shutdown() {
94 InitializeManagedStaticMutex();
95 std::lock_guard Lock(*ManagedStaticMutex);
96
9777 while (StaticList)
9878 StaticList->destroy();
79
80 if (llvm_is_multithreaded()) llvm_stop_multithreaded();
9981 }
66 //
77 //===----------------------------------------------------------------------===//
88 //
9 // This file implements helper functions for running LLVM in a multi-threaded
10 // environment.
9 // This file implements llvm_start_multithreaded() and friends.
1110 //
1211 //===----------------------------------------------------------------------===//
1312
1918
2019 using namespace llvm;
2120
22 bool llvm::llvm_is_multithreaded() {
21 static bool multithreaded_mode = false;
22
23 static sys::Mutex* global_lock = nullptr;
24
25 bool llvm::llvm_start_multithreaded() {
2326 #if LLVM_ENABLE_THREADS != 0
27 assert(!multithreaded_mode && "Already multithreaded!");
28 multithreaded_mode = true;
29 global_lock = new sys::Mutex(true);
30
31 // We fence here to ensure that all initialization is complete BEFORE we
32 // return from llvm_start_multithreaded().
33 sys::MemoryFence();
2434 return true;
2535 #else
2636 return false;
2737 #endif
38 }
39
40 void llvm::llvm_stop_multithreaded() {
41 #if LLVM_ENABLE_THREADS != 0
42 assert(multithreaded_mode && "Not currently multithreaded!");
43
44 // We fence here to insure that all threaded operations are complete BEFORE we
45 // return from llvm_stop_multithreaded().
46 sys::MemoryFence();
47
48 multithreaded_mode = false;
49 delete global_lock;
50 #endif
51 }
52
53 bool llvm::llvm_is_multithreaded() {
54 return multithreaded_mode;
55 }
56
57 void llvm::llvm_acquire_global_lock() {
58 if (multithreaded_mode) global_lock->acquire();
59 }
60
61 void llvm::llvm_release_global_lock() {
62 if (multithreaded_mode) global_lock->release();
2863 }
2964
3065 #if LLVM_ENABLE_THREADS != 0 && defined(HAVE_PTHREAD_H)
1717 #include "llvm/Support/FileSystem.h"
1818 #include "llvm/Support/Format.h"
1919 #include "llvm/Support/ManagedStatic.h"
20 #include "llvm/Support/MutexGuard.h"
20 #include "llvm/Support/Mutex.h"
2121 #include "llvm/Support/Process.h"
2222 #include "llvm/Support/raw_ostream.h"
2323 using namespace llvm;
8383 sys::MemoryFence();
8484 if (tmp) return tmp;
8585
86 sys::SmartScopedLock Lock(*TimerLock);
86 llvm_acquire_global_lock();
8787 tmp = DefaultTimerGroup;
8888 if (!tmp) {
8989 tmp = new TimerGroup("Miscellaneous Ungrouped Timers");
9090 sys::MemoryFence();
9191 DefaultTimerGroup = tmp;
9292 }
93 llvm_release_global_lock();
9394
9495 return tmp;
9596 }
4646 void *p1 = test1::allocate_stack(a1);
4747 void *p2 = test1::allocate_stack(a2);
4848
49 llvm_start_multithreaded();
4950 pthread_t t1, t2;
5051 pthread_create(&t1, &a1, test1::helper, nullptr);
5152 pthread_create(&t2, &a2, test1::helper, nullptr);
5354 pthread_join(t2, nullptr);
5455 free(p1);
5556 free(p2);
57 llvm_stop_multithreaded();
5658 }
5759 #endif
5860