1#pragma once
2
3#include <Common/VariableContext.h>
4#include <atomic>
5#include <memory>
6#include <stddef.h>
7
8/** Implements global counters for various events happening in the application
9 * - for high level profiling.
10 * See .cpp for list of events.
11 */
12
13namespace ProfileEvents
14{
15 /// Event identifier (index in array).
16 using Event = size_t;
17 using Count = size_t;
18 using Counter = std::atomic<Count>;
19 class Counters;
20
21 /// Counters - how many times each event happened
22 extern Counters global_counters;
23
24 class Counters
25 {
26 Counter * counters = nullptr;
27 std::unique_ptr<Counter[]> counters_holder;
28 /// Used to propagate increments
29 Counters * parent = nullptr;
30
31 public:
32
33 VariableContext level = VariableContext::Thread;
34
35 /// By default, any instance have to increment global counters
36 Counters(VariableContext level_ = VariableContext::Thread, Counters * parent_ = &global_counters);
37
38 /// Global level static initializer
39 Counters(Counter * allocated_counters)
40 : counters(allocated_counters), parent(nullptr), level(VariableContext::Global) {}
41
42 Counter & operator[] (Event event)
43 {
44 return counters[event];
45 }
46
47 const Counter & operator[] (Event event) const
48 {
49 return counters[event];
50 }
51
52 inline void increment(Event event, Count amount = 1)
53 {
54 Counters * current = this;
55 do
56 {
57 current->counters[event].fetch_add(amount, std::memory_order_relaxed);
58 current = current->parent;
59 } while (current != nullptr);
60 }
61
62 /// Every single value is fetched atomically, but not all values as a whole.
63 Counters getPartiallyAtomicSnapshot() const;
64
65 /// Reset all counters to zero and reset parent.
66 void reset();
67
68 /// Get parent (thread unsafe)
69 Counters * getParent()
70 {
71 return parent;
72 }
73
74 /// Set parent (thread unsafe)
75 void setParent(Counters * parent_)
76 {
77 parent = parent_;
78 }
79
80 /// Set all counters to zero
81 void resetCounters();
82
83 static const Event num_counters;
84 };
85
86 /// Increment a counter for event. Thread-safe.
87 void increment(Event event, Count amount = 1);
88
89 /// Get name of event by identifier. Returns statically allocated string.
90 const char * getName(Event event);
91
92 /// Get description of event by identifier. Returns statically allocated string.
93 const char * getDocumentation(Event event);
94
95 /// Get index just after last event identifier.
96 Event end();
97}
98