master
c 180 lines 6.81 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #define PULSE_INTERNALS 1
4 #include "pulse-aral.h"
5
6 struct aral_info {
7 const char *name;
8 RRDSET *st_memory;
9 RRDDIM *rd_malloc_used, *rd_malloc_free, *rd_mmap_used, *rd_mmap_free, *rd_structures, *rd_padding;
10
11 RRDSET *st_utilization;
12 RRDDIM *rd_utilization;
13 };
14
15 DEFINE_JUDYL_TYPED(ARAL_STATS, struct aral_info *);
16
17 static struct {
18 SPINLOCK spinlock;
19 ARAL_STATS_JudyLSet idx;
20 } globals = { 0 };
21
22 void pulse_aral_register_statistics(struct aral_statistics *stats, const char *name) {
23 if(!name || !stats)
24 return;
25
26 spinlock_lock(&globals.spinlock);
27 struct aral_info *ai = ARAL_STATS_GET(&globals.idx, (Word_t)stats);
28 if(!ai) {
29 ai = callocz(1, sizeof(struct aral_info));
30 ai->name = strdupz(name);
31 ARAL_STATS_SET(&globals.idx, (Word_t)stats, ai);
32 }
33 spinlock_unlock(&globals.spinlock);
34 }
35
36 void pulse_aral_unregister_statistics(struct aral_statistics *stats) {
37 spinlock_lock(&globals.spinlock);
38 struct aral_info *ai = ARAL_STATS_GET(&globals.idx, (Word_t)stats);
39 if(ai) {
40 ARAL_STATS_DEL(&globals.idx, (Word_t)stats);
41 freez((void *)ai->name);
42 freez(ai);
43 }
44 spinlock_unlock(&globals.spinlock);
45 }
46
47 void pulse_aral_register(ARAL *ar, const char *name) {
48 if(!ar) return;
49
50 if(!name)
51 name = aral_name(ar);
52
53 struct aral_statistics *stats = aral_get_statistics(ar);
54
55 pulse_aral_register_statistics(stats, name);
56 }
57
58 void pulse_aral_unregister(ARAL *ar) {
59 if(!ar) return;
60 struct aral_statistics *stats = aral_get_statistics(ar);
61 pulse_aral_unregister_statistics(stats);
62 }
63
64 void pulse_aral_init(void) {
65 pulse_aral_register_statistics(aral_by_size_statistics(), "by-size");
66 pulse_aral_register_statistics(judy_aral_statistics(), "judy");
67 pulse_aral_register_statistics(uuidmap_aral_statistics(), "uuidmap");
68 }
69
70 void pulse_aral_do(bool extended) {
71 if(!extended) return;
72
73 spinlock_lock(&globals.spinlock);
74 Word_t s = 0;
75 for(struct aral_info *ai = ARAL_STATS_FIRST(&globals.idx, &s);
76 ai;
77 ai = ARAL_STATS_NEXT(&globals.idx, &s)) {
78 struct aral_statistics *stats = (void *)(uintptr_t)s;
79 if (!stats)
80 continue;
81
82 size_t malloc_allocated_bytes = __atomic_load_n(&stats->malloc.allocated_bytes, __ATOMIC_RELAXED);
83 size_t malloc_used_bytes = __atomic_load_n(&stats->malloc.used_bytes, __ATOMIC_RELAXED);
84 if(malloc_used_bytes > malloc_allocated_bytes)
85 malloc_allocated_bytes = malloc_used_bytes;
86 size_t malloc_free_bytes = malloc_allocated_bytes - malloc_used_bytes;
87
88 size_t mmap_allocated_bytes = __atomic_load_n(&stats->mmap.allocated_bytes, __ATOMIC_RELAXED);
89 size_t mmap_used_bytes = __atomic_load_n(&stats->mmap.used_bytes, __ATOMIC_RELAXED);
90 if(mmap_used_bytes > mmap_allocated_bytes)
91 mmap_allocated_bytes = mmap_used_bytes;
92 size_t mmap_free_bytes = mmap_allocated_bytes - mmap_used_bytes;
93
94 size_t allocated_total = malloc_allocated_bytes + mmap_allocated_bytes;
95 size_t used_total = malloc_used_bytes + mmap_used_bytes;
96
97 size_t structures_bytes = __atomic_load_n(&stats->structures.allocated_bytes, __ATOMIC_RELAXED);
98
99 size_t padding_bytes = __atomic_load_n(&stats->malloc.padding_bytes, __ATOMIC_RELAXED) +
100 __atomic_load_n(&stats->mmap.padding_bytes, __ATOMIC_RELAXED);
101
102 NETDATA_DOUBLE utilization;
103 if(allocated_total)
104 utilization = 100.0 * (NETDATA_DOUBLE)used_total / (NETDATA_DOUBLE)allocated_total;
105 else
106 utilization = 100.0;
107
108 {
109 if (unlikely(!ai->st_memory)) {
110 char id[256];
111
112 snprintfz(id, sizeof(id), "aral_%s_memory", ai->name);
113 netdata_fix_chart_id(id);
114
115 ai->st_memory = rrdset_create_localhost(
116 "netdata",
117 id,
118 NULL,
119 "ARAL",
120 "netdata.aral_memory",
121 "Array Allocator Memory Utilization",
122 "bytes",
123 "netdata",
124 "pulse",
125 910000,
126 localhost->rrd_update_every,
127 RRDSET_TYPE_STACKED);
128
129 rrdlabels_add(ai->st_memory->rrdlabels, "ARAL", ai->name, RRDLABEL_SRC_AUTO);
130
131 ai->rd_malloc_free = rrddim_add(ai->st_memory, "malloc free", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
132 ai->rd_mmap_free = rrddim_add(ai->st_memory, "mmap free", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
133 ai->rd_malloc_used = rrddim_add(ai->st_memory, "malloc used", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
134 ai->rd_mmap_used = rrddim_add(ai->st_memory, "mmap used", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
135 ai->rd_structures = rrddim_add(ai->st_memory, "structures", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
136 ai->rd_padding = rrddim_add(ai->st_memory, "padding", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
137 }
138
139 rrddim_set_by_pointer(ai->st_memory, ai->rd_malloc_used, (collected_number)malloc_used_bytes);
140 rrddim_set_by_pointer(ai->st_memory, ai->rd_malloc_free, (collected_number)malloc_free_bytes);
141 rrddim_set_by_pointer(ai->st_memory, ai->rd_mmap_used, (collected_number)mmap_used_bytes);
142 rrddim_set_by_pointer(ai->st_memory, ai->rd_mmap_free, (collected_number)mmap_free_bytes);
143 rrddim_set_by_pointer(ai->st_memory, ai->rd_structures, (collected_number)structures_bytes);
144 rrddim_set_by_pointer(ai->st_memory, ai->rd_padding, (collected_number)padding_bytes);
145 rrdset_done(ai->st_memory);
146 }
147
148 {
149 if (unlikely(!ai->st_utilization)) {
150 char id[256];
151
152 snprintfz(id, sizeof(id), "aral_%s_utilization", ai->name);
153 netdata_fix_chart_id(id);
154
155 ai->st_utilization = rrdset_create_localhost(
156 "netdata",
157 id,
158 NULL,
159 "ARAL",
160 "netdata.aral_utilization",
161 "Array Allocator Memory Utilization",
162 "%",
163 "netdata",
164 "pulse",
165 910001,
166 localhost->rrd_update_every,
167 RRDSET_TYPE_LINE);
168
169 rrdlabels_add(ai->st_utilization->rrdlabels, "ARAL", ai->name, RRDLABEL_SRC_AUTO);
170
171 ai->rd_utilization = rrddim_add(ai->st_utilization, "utilization", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
172 }
173
174 rrddim_set_by_pointer(ai->st_utilization, ai->rd_utilization, (collected_number)(utilization * 1000.0));
175 rrdset_done(ai->st_utilization);
176 }
177 }
178
179 spinlock_unlock(&globals.spinlock);
180 }