-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcounters.cpp
More file actions
87 lines (73 loc) · 2.44 KB
/
counters.cpp
File metadata and controls
87 lines (73 loc) · 2.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include "counters.h"
#include "public/perfmon/thread_specific_counters.h"
#include <deque>
#include <mutex>
namespace perfmon {
namespace internal {
namespace {
struct GlobalCounter {
explicit GlobalCounter(const char *name)
: name(name), commited_calls(0), commited_ticks(0) {}
std::string name;
uint_fast64_t commited_calls;
uint_fast64_t commited_ticks;
uint_fast64_t accumulated_calls;
uint_fast64_t accumulated_ticks;
};
std::deque<GlobalCounter> &GlobalCounters() {
static auto *const result = new std::deque<GlobalCounter>();
return *result;
}
void UnsafeResetAccumulators() {
auto &global_counters = GlobalCounters();
for (auto &global_counter : global_counters) {
global_counter.accumulated_calls = 0;
global_counter.accumulated_ticks = 0;
}
}
} // namespace
std::unique_lock<std::mutex> GlobalLockGuard() {
static auto *const lock = new std::mutex;
return std::unique_lock<std::mutex>(*lock);
}
Counters GetCounters() {
const auto guard = GlobalLockGuard();
UnsafeResetAccumulators();
UnsafeFlushTssCounters();
auto &global_counters = GlobalCounters();
Counters result;
result.reserve(global_counters.size());
for (const auto &global_counter : global_counters) {
result.emplace_back(
&global_counter.name,
global_counter.commited_calls + global_counter.accumulated_calls,
global_counter.commited_ticks + global_counter.accumulated_ticks);
}
return result;
}
size_t GetCounterIndex(const char *counter_name) {
const auto guard = GlobalLockGuard();
auto &global_counters = GlobalCounters();
for (size_t i = 0; i < global_counters.size(); ++i) {
if (global_counters[i].name == counter_name) {
return i;
}
}
global_counters.emplace_back(counter_name);
return global_counters.size() - 1;
}
size_t UnsafeNumberOfCounters() { return GlobalCounters().size(); }
void UnsafeAccumulate(size_t counter_index, uint_fast64_t calls,
uint_fast64_t ticks) {
auto &global_counters = GlobalCounters();
global_counters.at(counter_index).accumulated_calls += calls;
global_counters.at(counter_index).accumulated_ticks += ticks;
}
void UnsafeCommit(size_t counter_index, uint_fast64_t calls,
uint_fast64_t ticks) {
auto &global_counters = GlobalCounters();
global_counters.at(counter_index).commited_calls += calls;
global_counters.at(counter_index).commited_ticks += ticks;
}
} // namespace internal
} // namespace perfmon