#ifndef LLVM_SUPPORT_MANAGEDSTATIC_H
#define LLVM_SUPPORT_MANAGEDSTATIC_H
-#include "llvm/Support/Atomic.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Threading.h"
+#include <atomic>
+#include <cstddef>
namespace llvm {
protected:
// This should only be used as a static variable, which guarantees that this
// will be zero initialized.
- mutable void *Ptr;
+ mutable std::atomic<void *> Ptr;
mutable void (*DeleterFn)(void*);
mutable const ManagedStaticBase *Next;
template<class C>
class ManagedStatic : public ManagedStaticBase {
public:
-
// Accessors.
C &operator*() {
- void* tmp = Ptr;
- if (llvm_is_multithreaded()) sys::MemoryFence();
- if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
- TsanHappensAfter(this);
+ void *Tmp = Ptr.load(std::memory_order_acquire);
+ if (!Tmp)
+ RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
- return *static_cast<C*>(Ptr);
+ return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
}
- C *operator->() {
- void* tmp = Ptr;
- if (llvm_is_multithreaded()) sys::MemoryFence();
- if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
- TsanHappensAfter(this);
- return static_cast<C*>(Ptr);
- }
+ C *operator->() { return &**this; }
+
const C &operator*() const {
- void* tmp = Ptr;
- if (llvm_is_multithreaded()) sys::MemoryFence();
- if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
- TsanHappensAfter(this);
+ void *Tmp = Ptr.load(std::memory_order_acquire);
+ if (!Tmp)
+ RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
- return *static_cast<C*>(Ptr);
+ return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
}
- const C *operator->() const {
- void* tmp = Ptr;
- if (llvm_is_multithreaded()) sys::MemoryFence();
- if (!tmp) RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
- TsanHappensAfter(this);
- return static_cast<C*>(Ptr);
- }
+ const C *operator->() const { return &**this; }
};
/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Config/config.h"
-#include "llvm/Support/Atomic.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/Support/Threading.h"
if (llvm_is_multithreaded()) {
MutexGuard Lock(*getManagedStaticMutex());
- if (!Ptr) {
- void* tmp = Creator();
+ if (!Ptr.load(std::memory_order_relaxed)) {
+ void *Tmp = Creator();
- TsanHappensBefore(this);
- sys::MemoryFence();
-
- // This write is racy against the first read in the ManagedStatic
- // accessors. The race is benign because it does a second read after a
- // memory fence, at which point it isn't possible to get a partial value.
- TsanIgnoreWritesBegin();
- Ptr = tmp;
- TsanIgnoreWritesEnd();
+ Ptr.store(Tmp, std::memory_order_release);
DeleterFn = Deleter;
// Add to list of managed statics.