4 // system event counters, for
6 #include <algorithm> // for std::max
18 enum Type { TYPE_COUNT, TYPE_AGG };
21 : type_(TYPE_COUNT), count_(0), sum_(0), max_(0) {}
29 operator+=(const counter_data &that)
31 count_ += that.count_;
33 max_ = std::max(max_, that.max_);
40 INVARIANT(type_ == TYPE_AGG);
41 return double(sum_)/double(count_);
47 // these objects are *never* supposed to be destructed
48 // (this is a purposeful memory leak)
51 static std::map<std::string, event_ctx *> &event_counters();
52 static spinlock &event_counters_lock();
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)
64 event_ctx(const event_ctx &) = delete;
65 event_ctx &operator=(const event_ctx &) = delete;
66 event_ctx(event_ctx &&) = delete;
68 void stat(counter_data &d);
70 const std::string name_;
74 percore<uint64_t, false, false> counts_;
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_;
87 event_counter(const std::string &name);
89 event_counter(const event_counter &) = delete;
90 event_counter &operator=(const event_counter &) = delete;
91 event_counter(event_counter &&) = delete;
93 inline ALWAYS_INLINE void
96 #ifdef ENABLE_EVENT_COUNTERS
97 ctx_->counts_.my() += i;
101 inline ALWAYS_INLINE event_counter &
108 inline ALWAYS_INLINE event_counter &
109 operator+=(uint64_t i)
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!
121 stat(const std::string &name, counter_data &d);
124 #ifdef ENABLE_EVENT_COUNTERS
125 unmanaged<private_::event_ctx> ctx_;
129 class event_avg_counter {
131 event_avg_counter(const std::string &name);
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;
137 inline ALWAYS_INLINE void
138 offer(uint64_t value)
140 #ifdef ENABLE_EVENT_COUNTERS
141 ctx_->counts_.my()++;
142 ctx_->sums_.my() += value;
143 ctx_->highs_.my() = std::max(ctx_->highs_.my(), value);
148 #ifdef ENABLE_EVENT_COUNTERS
149 unmanaged<private_::event_ctx_avg> ctx_;
153 inline std::ostream &
154 operator<<(std::ostream &o, const counter_data &d)
156 if (d.type_ == counter_data::TYPE_COUNT)
157 o << "count=" << d.count_;
159 o << "count=" << d.count_ << ", max=" << d.max_ << ", avg=" << d.avg();
163 #endif /* _COUNTER_H_ */