We need to use double-checked locking for lazy initialization in this case when runni...
authorOwen Anderson <resistor@mac.com>
Wed, 17 Jun 2009 21:16:20 +0000 (21:16 +0000)
committerOwen Anderson <resistor@mac.com>
Wed, 17 Jun 2009 21:16:20 +0000 (21:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73636 91177308-0d34-0410-b5e6-96231b3b80d8

lib/VMCore/Pass.cpp

index 6db5d7e24c5ef2f4eec9eb5cc0680261411ba4a6..bacabc96d76a41dc153de6c337757ae5ebc089e4 100644 (file)
@@ -19,6 +19,8 @@
 #include "llvm/ModuleProvider.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Threading.h"
+#include "llvm/System/Atomic.h"
 #include <algorithm>
 #include <map>
 #include <set>
@@ -192,8 +194,20 @@ static std::vector<PassRegistrationListener*> *Listeners = 0;
 // ressurection after llvm_shutdown is run.
 static PassRegistrar *getPassRegistrar() {
   static PassRegistrar *PassRegistrarObj = 0;
+  
+  // Use double-checked locking to safely initialize the registrar when
+  // we're running in multithreaded mode.
   if (!PassRegistrarObj)
-    PassRegistrarObj = new PassRegistrar();
+    if (llvm_is_multithreaded()) {
+      llvm_acquire_global_lock();
+      if (!PassRegistrarObj) {
+        PassRegistrar* tmp = new PassRegistrar();
+        sys::MemoryFence();
+        PassRegistrarObj = tmp;
+      }
+      llvm_release_global_lock();
+    } else
+      PassRegistrarObj = new PassRegistrar();
   return PassRegistrarObj;
 }