[llvm-commits] [llvm] r72151 - in /llvm/trunk: include/llvm/Support/ManagedStatic.h lib/Support/ManagedStatic.cpp
Owen Anderson
resistor at mac.com
Tue May 19 17:39:26 PDT 2009
Author: resistor
Date: Tue May 19 19:39:20 2009
New Revision: 72151
URL: http://llvm.org/viewvc/llvm-project?rev=72151&view=rev
Log:
Add llvm_start_multithreaded(), which starts up the LLVM internals in thread-safe mode. Provide double-check locking
initialization of ManagedStatic's when running in thread-safe mode.
Modified:
llvm/trunk/include/llvm/Support/ManagedStatic.h
llvm/trunk/lib/Support/ManagedStatic.cpp
Modified: llvm/trunk/include/llvm/Support/ManagedStatic.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ManagedStatic.h?rev=72151&r1=72150&r2=72151&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/ManagedStatic.h (original)
+++ llvm/trunk/include/llvm/Support/ManagedStatic.h Tue May 19 19:39:20 2009
@@ -14,8 +14,16 @@
#ifndef LLVM_SUPPORT_MANAGED_STATIC_H
#define LLVM_SUPPORT_MANAGED_STATIC_H
+#include "llvm/System/Atomic.h"
+
namespace llvm {
+/// object_creator - Helper method for ManagedStatic.
+template<class C>
+void* object_creator() {
+ return new C();
+}
+
/// object_deleter - Helper method for ManagedStatic.
///
template<class C>
@@ -32,7 +40,7 @@
mutable void (*DeleterFn)(void*);
mutable const ManagedStaticBase *Next;
- void RegisterManagedStatic(void *ObjPtr, void (*deleter)(void*)) const;
+ void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const;
public:
/// isConstructed - Return true if this object has not been created yet.
bool isConstructed() const { return Ptr != 0; }
@@ -51,25 +59,32 @@
// Accessors.
C &operator*() {
- if (!Ptr) LazyInit();
+ void* tmp = Ptr;
+ sys::MemoryFence();
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
+
return *static_cast<C*>(Ptr);
}
C *operator->() {
- if (!Ptr) LazyInit();
+ void* tmp = Ptr;
+ sys::MemoryFence();
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
+
return static_cast<C*>(Ptr);
}
const C &operator*() const {
- if (!Ptr) LazyInit();
+ void* tmp = Ptr;
+ sys::MemoryFence();
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
+
return *static_cast<C*>(Ptr);
}
const C *operator->() const {
- if (!Ptr) LazyInit();
- return static_cast<C*>(Ptr);
- }
+ void* tmp = Ptr;
+ sys::MemoryFence();
+ if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>);
-public:
- void LazyInit() const {
- RegisterManagedStatic(new C(), object_deleter<C>);
+ return static_cast<C*>(Ptr);
}
};
@@ -80,6 +95,10 @@
};
+/// llvm_start_multithreaded - Allocate and initialize structures needed to
+/// make LLVM safe for multithreading.
+void llvm_start_multithreaded();
+
/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
void llvm_shutdown();
@@ -87,7 +106,10 @@
/// llvm_shutdown_obj - This is a simple helper class that calls
/// llvm_shutdown() when it is destroyed.
struct llvm_shutdown_obj {
- llvm_shutdown_obj() {}
+ llvm_shutdown_obj() { }
+ explicit llvm_shutdown_obj(bool multithreaded) {
+ if (multithreaded) llvm_start_multithreaded();
+ }
~llvm_shutdown_obj() { llvm_shutdown(); }
};
Modified: llvm/trunk/lib/Support/ManagedStatic.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/ManagedStatic.cpp?rev=72151&r1=72150&r2=72151&view=diff
==============================================================================
--- llvm/trunk/lib/Support/ManagedStatic.cpp (original)
+++ llvm/trunk/lib/Support/ManagedStatic.cpp Tue May 19 19:39:20 2009
@@ -12,21 +12,44 @@
//===----------------------------------------------------------------------===//
#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;
-void ManagedStaticBase::RegisterManagedStatic(void *ObjPtr,
+static sys::Mutex* ManagedStaticMutex = 0;
+
+void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
void (*Deleter)(void*)) const {
- assert(Ptr == 0 && DeleterFn == 0 && Next == 0 &&
- "Partially init static?");
- Ptr = ObjPtr;
- DeleterFn = Deleter;
+ if (ManagedStaticMutex) {
+ ManagedStaticMutex->acquire();
+
+ if (Ptr == 0) {
+ void* tmp = Creator ? Creator() : 0;
+
+ sys::MemoryFence();
+ Ptr = tmp;
+ DeleterFn = Deleter;
+
+ // Add to list of managed statics.
+ Next = StaticList;
+ StaticList = this;
+ }
+
+ ManagedStaticMutex->release();
+ } else {
+ assert(Ptr == 0 && DeleterFn == 0 && Next == 0 &&
+ "Partially initialized ManagedStatic!?");
+ Ptr = Creator ? Creator() : 0;
+ DeleterFn = Deleter;
- // Add to list of managed statics.
- Next = StaticList;
- StaticList = this;
+ // Add to list of managed statics.
+ Next = StaticList;
+ StaticList = this;
+ }
}
void ManagedStaticBase::destroy() const {
@@ -45,9 +68,23 @@
DeleterFn = 0;
}
+void llvm::llvm_start_multithreaded() {
+#if LLVM_MULTITHREADED
+ assert(ManagedStaticMutex == 0 && "Multithreaded LLVM already initialized!");
+ ManagedStaticMutex = new sys::Mutex(true);
+#else
+ assert(0 && "LLVM built without multithreading support!");
+#endif
+}
+
/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
void llvm::llvm_shutdown() {
while (StaticList)
StaticList->destroy();
+
+ if (ManagedStaticMutex) {
+ delete ManagedStaticMutex;
+ ManagedStaticMutex = 0;
+ }
}
More information about the llvm-commits
mailing list