-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathnativeMem.cpp
More file actions
109 lines (99 loc) · 3.14 KB
/
Copy pathnativeMem.cpp
File metadata and controls
109 lines (99 loc) · 3.14 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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
* Copyright 2026, Datadog, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#include "nativeMem.h"
volatile long long NativeMem::_live[NM_NUM_CATEGORIES] = {};
volatile long long NativeMem::_max[NM_NUM_CATEGORIES] = {};
long long NativeMem::_window[NM_NUM_CATEGORIES][NativeMem::WINDOW] = {};
long long NativeMem::_total_window[NativeMem::WINDOW] = {};
int NativeMem::_window_pos = 0;
int NativeMem::_window_count = 0;
long long NativeMem::_avg[NM_NUM_CATEGORIES] = {};
long long NativeMem::_total_avg = 0;
long long NativeMem::_total_max_observed = 0;
long long NativeMem::liveTotal() {
long long total = 0;
for (int c = 0; c < NM_NUM_CATEGORIES; c++) {
// Clamp per-category negatives to 0 (see sample()): the total is exported
// as an unsigned varint, so a stray negative would otherwise serialize as a
// huge value and corrupt the counter stream.
long long v = load(_live[c]);
if (v > 0) {
total += v;
}
}
return total;
}
long long NativeMem::maxTotal() {
long long total = 0;
for (int c = 0; c < NM_NUM_CATEGORIES; c++) {
total += load(_max[c]);
}
return total;
}
void NativeMem::sample() {
long long total = 0;
for (int c = 0; c < NM_NUM_CATEGORIES; c++) {
long long v = load(_live[c]);
// A category's live bytes are never negative under correct pairing (asserted
// in record()). This clamp is a release-mode safety net: should an accounting
// bug slip past the assert under NDEBUG, it keeps a negative from skewing the
// window average and total rather than propagating garbage.
if (v < 0) {
v = 0;
}
_window[c][_window_pos] = v;
total += v;
}
// The per-category peaks are maintained precisely at allocation time by
// record(); here we only track the largest observed total. Note `total` is a
// non-atomic sum of the per-category gauges read moments apart, so it is an
// approximate sampled figure, not a strict instantaneous total.
_total_window[_window_pos] = total;
if (total > _total_max_observed) {
_total_max_observed = total;
}
_window_pos = (_window_pos + 1) % WINDOW;
if (_window_count < WINDOW) {
_window_count++;
}
for (int c = 0; c < NM_NUM_CATEGORIES; c++) {
long long sum = 0;
for (int i = 0; i < _window_count; i++) {
sum += _window[c][i];
}
_avg[c] = sum / _window_count;
}
long long total_sum = 0;
for (int i = 0; i < _window_count; i++) {
total_sum += _total_window[i];
}
_total_avg = total_sum / _window_count;
}
void NativeMem::reset() {
for (int c = 0; c < NM_NUM_CATEGORIES; c++) {
store(_live[c], (long long)0);
store(_max[c], (long long)0);
_avg[c] = 0;
for (int i = 0; i < WINDOW; i++) {
_window[c][i] = 0;
}
}
for (int i = 0; i < WINDOW; i++) {
_total_window[i] = 0;
}
_window_pos = 0;
_window_count = 0;
_total_avg = 0;
_total_max_observed = 0;
}
const char *NativeMem::categoryName(NativeMemCategory category) {
#define X_NM_NAME(a, b) b,
static const char *const names[] = {DD_NATIVE_MEM_CATEGORY_TABLE(X_NM_NAME)};
#undef X_NM_NAME
if (category < 0 || category >= NM_NUM_CATEGORIES) {
return "unknown";
}
return names[category];
}