Clean up build and remove generated files
[c11concurrency-benchmarks.git] / silo / counter.h
1 #ifndef _COUNTER_H_
2 #define _COUNTER_H_
3
4 // system event counters, for
5
6 #include <algorithm> // for std::max
7 #include <vector>
8 #include <map>
9 #include <string>
10 #include <stdint.h>
11
12 #include "macros.h"
13 #include "core.h"
14 #include "util.h"
15 #include "spinlock.h"
16
17 struct counter_data {
18   enum Type { TYPE_COUNT, TYPE_AGG };
19
20   counter_data()
21     : type_(TYPE_COUNT), count_(0), sum_(0), max_(0) {}
22
23   Type type_;
24   uint64_t count_;
25   uint64_t sum_;
26   uint64_t max_;
27
28   inline counter_data &
29   operator+=(const counter_data &that)
30   {
31     count_ += that.count_;
32     sum_   += that.sum_;
33     max_    = std::max(max_, that.max_);
34     return *this;
35   }
36
37   inline double
38   avg() const
39   {
40     INVARIANT(type_ == TYPE_AGG);
41     return double(sum_)/double(count_);
42   }
43 };
44
45 namespace private_ {
46
47   // these objects are *never* supposed to be destructed
48   // (this is a purposeful memory leak)
49   struct event_ctx {
50
51     static std::map<std::string, event_ctx *> &event_counters();
52     static spinlock &event_counters_lock();
53
54     // tag to avoid making event_ctx virtual
55     event_ctx(const std::string &name, bool avg_tag)
56       : name_(name), avg_tag_(avg_tag)
57     {}
58
59     ~event_ctx()
60     {
61       ALWAYS_ASSERT(false);
62     }
63
64     event_ctx(const event_ctx &) = delete;
65     event_ctx &operator=(const event_ctx &) = delete;
66     event_ctx(event_ctx &&) = delete;
67
68     void stat(counter_data &d);
69
70     const std::string name_;
71     const bool avg_tag_;
72
73     // per-thread counts
74     percore<uint64_t, false, false> counts_;
75   };
76
77   // more expensive
78   struct event_ctx_avg : public event_ctx {
79     event_ctx_avg(const std::string &name) : event_ctx(name, true) {}
80     percore<uint64_t, false, false> sums_;
81     percore<uint64_t, false, false> highs_;
82   };
83 }
84
85 class event_counter {
86 public:
87   event_counter(const std::string &name);
88
89   event_counter(const event_counter &) = delete;
90   event_counter &operator=(const event_counter &) = delete;
91   event_counter(event_counter &&) = delete;
92
93   inline ALWAYS_INLINE void
94   inc(uint64_t i = 1)
95   {
96 #ifdef ENABLE_EVENT_COUNTERS
97     ctx_->counts_.my() += i;
98 #endif
99   }
100
101   inline ALWAYS_INLINE event_counter &
102   operator++()
103   {
104     inc();
105     return *this;
106   }
107
108   inline ALWAYS_INLINE event_counter &
109   operator+=(uint64_t i)
110   {
111     inc(i);
112     return *this;
113   }
114
115   // WARNING: an expensive operation!
116   static std::map<std::string, counter_data> get_all_counters();
117   // WARNING: an expensive operation!
118   static void reset_all_counters();
119   // WARNING: an expensive operation!
120   static bool
121   stat(const std::string &name, counter_data &d);
122
123 private:
124 #ifdef ENABLE_EVENT_COUNTERS
125   unmanaged<private_::event_ctx> ctx_;
126 #endif
127 };
128
129 class event_avg_counter {
130 public:
131   event_avg_counter(const std::string &name);
132
133   event_avg_counter(const event_avg_counter &) = delete;
134   event_avg_counter &operator=(const event_avg_counter &) = delete;
135   event_avg_counter(event_avg_counter &&) = delete;
136
137   inline ALWAYS_INLINE void
138   offer(uint64_t value)
139   {
140 #ifdef ENABLE_EVENT_COUNTERS
141     ctx_->counts_.my()++;
142     ctx_->sums_.my() += value;
143     ctx_->highs_.my() = std::max(ctx_->highs_.my(), value);
144 #endif
145   }
146
147 private:
148 #ifdef ENABLE_EVENT_COUNTERS
149   unmanaged<private_::event_ctx_avg> ctx_;
150 #endif
151 };
152
153 inline std::ostream &
154 operator<<(std::ostream &o, const counter_data &d)
155 {
156   if (d.type_ == counter_data::TYPE_COUNT)
157     o << "count=" << d.count_;
158   else
159     o << "count=" << d.count_ << ", max=" << d.max_ << ", avg=" << d.avg();
160   return o;
161 }
162
163 #endif /* _COUNTER_H_ */