llvm.org GIT mirror llvm / 4721e55
[C++11] Replace LLVM atomics with std::atomic. With C++11 we finally have a standardized way to specify atomic operations. Use them to replace the existing custom implemention. Sadly the translation is not entirely trivial as std::atomic allows more fine-grained control over the atomicity. I tried to preserve the old semantics as well as possible. Differential Revision: http://llvm-reviews.chandlerc.com/D2915 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202730 91177308-0d34-0410-b5e6-96231b3b80d8 Benjamin Kramer 6 years ago
9 changed file(s) with 49 addition(s) and 41 deletion(s). Raw diff Collapse all Expand all
2525 #ifndef LLVM_ADT_STATISTIC_H
2626 #define LLVM_ADT_STATISTIC_H
2727
28 #include "llvm/Support/Atomic.h"
2928 #include "llvm/Support/Valgrind.h"
29 #include
3030
3131 namespace llvm {
3232 class raw_ostream;
3535 public:
3636 const char *Name;
3737 const char *Desc;
38 volatile llvm::sys::cas_flag Value;
38 std::atomic Value;
3939 bool Initialized;
4040
41 llvm::sys::cas_flag getValue() const { return Value; }
41 unsigned getValue() const { return Value; }
4242 const char *getName() const { return Name; }
4343 const char *getDesc() const { return Desc; }
4444
6262 // atomic operation to update the value safely in the presence of
6363 // concurrent accesses, but not to read the return value, so the
6464 // return value is not thread safe.
65 sys::AtomicIncrement(&Value);
65 ++Value;
6666 return init();
6767 }
6868
6969 unsigned operator++(int) {
7070 init();
71 unsigned OldValue = Value;
72 sys::AtomicIncrement(&Value);
71 unsigned OldValue = Value++;
7372 return OldValue;
7473 }
7574
7675 const Statistic &operator--() {
77 sys::AtomicDecrement(&Value);
76 --Value;
7877 return init();
7978 }
8079
8180 unsigned operator--(int) {
8281 init();
83 unsigned OldValue = Value;
84 sys::AtomicDecrement(&Value);
82 unsigned OldValue = Value--;
8583 return OldValue;
8684 }
8785
8886 const Statistic &operator+=(const unsigned &V) {
8987 if (!V) return *this;
90 sys::AtomicAdd(&Value, V);
88 Value += V;
9189 return init();
9290 }
9391
9492 const Statistic &operator-=(const unsigned &V) {
9593 if (!V) return *this;
96 sys::AtomicAdd(&Value, -V);
94 Value -= V;
9795 return init();
9896 }
9997
10098 const Statistic &operator*=(const unsigned &V) {
101 sys::AtomicMul(&Value, V);
99 unsigned Original, Result;
100 do {
101 Original = Value;
102 Result = Original * V;
103 } while (!Value.compare_exchange_strong(Original, Result));
102104 return init();
103105 }
104106
105107 const Statistic &operator/=(const unsigned &V) {
106 sys::AtomicDiv(&Value, V);
108 unsigned Original, Result;
109 do {
110 Original = Value;
111 Result = Original / V;
112 } while (!Value.compare_exchange_strong(Original, Result));
107113 return init();
108114 }
109115
150156 protected:
151157 Statistic &init() {
152158 bool tmp = Initialized;
153 sys::MemoryFence();
159 std::atomic_thread_fence(std::memory_order_seq_cst);
154160 if (!tmp) RegisterStatistic();
155161 TsanHappensAfter(this);
156162 return *this;
161167 // STATISTIC - A macro to make definition of statistics really simple. This
162168 // automatically passes the DEBUG_TYPE of the file into the statistic.
163169 #define STATISTIC(VARNAME, DESC) \
164 static llvm::Statistic VARNAME = { DEBUG_TYPE, DESC, 0, 0 }
170 static llvm::Statistic VARNAME = { DEBUG_TYPE, DESC, {}, 0 }
165171
166172 /// \brief Enable the collection and printing of statistics.
167173 void EnableStatistics();
2323 #include "Pass.h"
2424 #include "llvm/InitializePasses.h"
2525 #include "llvm/PassRegistry.h"
26 #include "llvm/Support/Atomic.h"
2726 #include "llvm/Support/Valgrind.h"
27 #include
2828 #include
2929
3030 namespace llvm {
146146 };
147147
148148 #define CALL_ONCE_INITIALIZATION(function) \
149 static volatile sys::cas_flag initialized = 0; \
150 sys::cas_flag old_val = sys::CompareAndSwap(&initialized, 1, 0); \
151 if (old_val == 0) { \
149 static std::atomic initialized; \
150 int old_val = 0; \
151 if (initialized.compare_exchange_strong(old_val, 1)) { \
152152 function(Registry); \
153 sys::MemoryFence(); \
153 std::atomic_thread_fence(std::memory_order_seq_cst); \
154154 TsanIgnoreWritesBegin(); \
155155 TsanHappensBefore(&initialized); \
156156 initialized = 2; \
157157 TsanIgnoreWritesEnd(); \
158158 } else { \
159 sys::cas_flag tmp = initialized; \
160 sys::MemoryFence(); \
159 int tmp = initialized.load(); \
160 std::atomic_thread_fence(std::memory_order_seq_cst); \
161161 while (tmp != 2) { \
162 tmp = initialized; \
163 sys::MemoryFence(); \
162 tmp = initialized.load(); \
163 std::atomic_thread_fence(std::memory_order_seq_cst); \
164164 } \
165165 } \
166166 TsanHappensAfter(&initialized);
1313 #ifndef LLVM_SUPPORT_MANAGED_STATIC_H
1414 #define LLVM_SUPPORT_MANAGED_STATIC_H
1515
16 #include "llvm/Support/Atomic.h"
1716 #include "llvm/Support/Threading.h"
1817 #include "llvm/Support/Valgrind.h"
18 #include
1919
2020 namespace llvm {
2121
6363 // Accessors.
6464 C &operator*() {
6565 void* tmp = Ptr;
66 if (llvm_is_multithreaded()) sys::MemoryFence();
66 if (llvm_is_multithreaded())
67 std::atomic_thread_fence(std::memory_order_seq_cst);
6768 if (!tmp) RegisterManagedStatic(object_creator, object_deleter::call);
6869 TsanHappensAfter(this);
6970
7172 }
7273 C *operator->() {
7374 void* tmp = Ptr;
74 if (llvm_is_multithreaded()) sys::MemoryFence();
75 if (llvm_is_multithreaded())
76 std::atomic_thread_fence(std::memory_order_seq_cst);
7577 if (!tmp) RegisterManagedStatic(object_creator, object_deleter::call);
7678 TsanHappensAfter(this);
7779
7981 }
8082 const C &operator*() const {
8183 void* tmp = Ptr;
82 if (llvm_is_multithreaded()) sys::MemoryFence();
84 if (llvm_is_multithreaded())
85 std::atomic_thread_fence(std::memory_order_seq_cst);
8386 if (!tmp) RegisterManagedStatic(object_creator, object_deleter::call);
8487 TsanHappensAfter(this);
8588
8790 }
8891 const C *operator->() const {
8992 void* tmp = Ptr;
90 if (llvm_is_multithreaded()) sys::MemoryFence();
93 if (llvm_is_multithreaded())
94 std::atomic_thread_fence(std::memory_order_seq_cst);
9195 if (!tmp) RegisterManagedStatic(object_creator, object_deleter::call);
9296 TsanHappensAfter(this);
9397
1717 #include "LLVMContextImpl.h"
1818 #include "llvm/ADT/StringExtras.h"
1919 #include "llvm/IR/Type.h"
20 #include "llvm/Support/Atomic.h"
2120 #include "llvm/Support/Debug.h"
2221 #include "llvm/Support/ManagedStatic.h"
2322 #include "llvm/Support/Mutex.h"
1818 #include "llvm/IR/Function.h"
1919 #include "llvm/IR/Instruction.h"
2020 #include "llvm/IR/Metadata.h"
21 #include "llvm/Support/Atomic.h"
21 #include
2222 #include
2323
2424 using namespace llvm;
2525
2626 int llvm::getNextAvailablePluginDiagnosticKind() {
27 static sys::cas_flag PluginKindID = DK_FirstPluginKind;
28 return (int)sys::AtomicIncrement(&PluginKindID);
27 static std::atomic PluginKindID(DK_FirstPluginKind);
28 return ++PluginKindID;
2929 }
3030
3131 DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
1212
1313 #include "llvm/Support/ManagedStatic.h"
1414 #include "llvm/Config/config.h"
15 #include "llvm/Support/Atomic.h"
1615 #include
1716 using namespace llvm;
1817
2726 void* tmp = Creator ? Creator() : 0;
2827
2928 TsanHappensBefore(this);
30 sys::MemoryFence();
29 std::atomic_thread_fence(std::memory_order_seq_cst);
3130
3231 // This write is racy against the first read in the ManagedStatic
3332 // accessors. The race is benign because it does a second read after a
7575 StatInfo->addStatistic(this);
7676
7777 TsanHappensBefore(this);
78 sys::MemoryFence();
78 std::atomic_thread_fence(std::memory_order_seq_cst);
7979 // Remember we have been registered.
8080 TsanIgnoreWritesBegin();
8181 Initialized = true;
1212
1313 #include "llvm/Support/Threading.h"
1414 #include "llvm/Config/config.h"
15 #include "llvm/Support/Atomic.h"
1615 #include "llvm/Support/Mutex.h"
16 #include
1717 #include
1818
1919 using namespace llvm;
3030
3131 // We fence here to ensure that all initialization is complete BEFORE we
3232 // return from llvm_start_multithreaded().
33 sys::MemoryFence();
33 std::atomic_thread_fence(std::memory_order_seq_cst);
3434 return true;
3535 #else
3636 return false;
4343
4444 // We fence here to insure that all threaded operations are complete BEFORE we
4545 // return from llvm_stop_multithreaded().
46 sys::MemoryFence();
46 std::atomic_thread_fence(std::memory_order_seq_cst);
4747
4848 multithreaded_mode = false;
4949 delete global_lock;
8080 static TimerGroup *DefaultTimerGroup = 0;
8181 static TimerGroup *getDefaultTimerGroup() {
8282 TimerGroup *tmp = DefaultTimerGroup;
83 sys::MemoryFence();
83 std::atomic_thread_fence(std::memory_order_seq_cst);
8484 if (tmp) return tmp;
8585
8686 llvm_acquire_global_lock();
8787 tmp = DefaultTimerGroup;
8888 if (!tmp) {
8989 tmp = new TimerGroup("Miscellaneous Ungrouped Timers");
90 sys::MemoryFence();
90 std::atomic_thread_fence(std::memory_order_seq_cst);
9191 DefaultTimerGroup = tmp;
9292 }
9393 llvm_release_global_lock();