llvm.org GIT mirror llvm / 92915e3
Use atomic operations when accessing statistics, and make the lazy initialization of statistics actually threadsafe. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74005 91177308-0d34-0410-b5e6-96231b3b80d8 Owen Anderson 11 years ago
2 changed file(s) with 63 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
2525 #ifndef LLVM_ADT_STATISTIC_H
2626 #define LLVM_ADT_STATISTIC_H
2727
28 #include "llvm/System/Atomic.h"
29
2830 namespace llvm {
2931
3032 class Statistic {
3133 public:
3234 const char *Name;
3335 const char *Desc;
34 unsigned Value : 31;
35 bool Initialized : 1;
36 unsigned Value;
37 bool Initialized;
3638
3739 unsigned getValue() const { return Value; }
3840 const char *getName() const { return Name; }
4648
4749 // Allow use of this class as the value itself.
4850 operator unsigned() const { return Value; }
49 const Statistic &operator=(unsigned Val) { Value = Val; return init(); }
50 const Statistic &operator++() { ++Value; return init(); }
51 unsigned operator++(int) { init(); return Value++; }
52 const Statistic &operator--() { --Value; return init(); }
53 unsigned operator--(int) { init(); return Value--; }
54 const Statistic &operator+=(const unsigned &V) { Value += V; return init(); }
55 const Statistic &operator-=(const unsigned &V) { Value -= V; return init(); }
56 const Statistic &operator*=(const unsigned &V) { Value *= V; return init(); }
57 const Statistic &operator/=(const unsigned &V) { Value /= V; return init(); }
51 const Statistic &operator=(unsigned Val) {
52 Value = Val;
53 return init();
54 }
55
56 const Statistic &operator++() {
57 sys::AtomicIncrement(&Value);
58 return init();
59 }
60
61 unsigned operator++(int) {
62 init();
63 unsigned OldValue = Value;
64 sys::AtomicIncrement(&Value);
65 return OldValue;
66 }
67
68 const Statistic &operator--() {
69 sys::AtomicDecrement(&Value);
70 return init();
71 }
72
73 unsigned operator--(int) {
74 init();
75 unsigned OldValue = Value;
76 sys::AtomicDecrement(&Value);
77 return OldValue;
78 }
79
80 const Statistic &operator+=(const unsigned &V) {
81 sys::AtomicAdd(&Value, V);
82 return init();
83 }
84
85 const Statistic &operator-=(const unsigned &V) {
86 sys::AtomicAdd(&Value, -V);
87 return init();
88 }
89
90 const Statistic &operator*=(const unsigned &V) {
91 sys::AtomicMul(&Value, V);
92 return init();
93 }
94
95 const Statistic &operator/=(const unsigned &V) {
96 sys::AtomicDiv(&Value, V);
97 return init();
98 }
5899
59100 protected:
60101 Statistic &init() {
61 if (!Initialized) RegisterStatistic();
102 bool tmp = Initialized;
103 sys::MemoryFence();
104 if (!tmp) RegisterStatistic();
62105 return *this;
63106 }
64107 void RegisterStatistic();
6565 // If stats are enabled, inform StatInfo that this statistic should be
6666 // printed.
6767 sys::ScopedLock Writer(&*StatLock);
68 if (Enabled)
69 StatInfo->addStatistic(this);
70 // Remember we have been registered.
71 Initialized = true;
68 if (!Initialized) {
69 if (Enabled)
70 StatInfo->addStatistic(this);
71
72 sys::MemoryFence();
73 // Remember we have been registered.
74 Initialized = true;
75 }
7276 }
7377
7478 namespace {