Branch data Line data Source code
1 : : #include "mem.h"
2 : :
3 : : Telemetry telemetry = {0};
4 : :
5 : : #ifndef ROUGH_DEBUG
6 : : #define ROUGH_DEBUG 0
7 : : #endif
8 : :
9 : : /**
10 : : * @brief Update the peak heap usage counter if @p updated_current_bytes exceeds it.
11 : : *
12 : : * Uses atomic compare-and-swap to record the highest observed heap footprint.
13 : : *
14 : : * @param updated_current_bytes Newly observed heap usage value.
15 : : */
16 : 3602 : static void telemetry_update_peak(const size_t updated_current_bytes)
17 : : {
18 : 3602 : size_t observed_peak = __atomic_load_n(&telemetry.peak_heap_bytes,__ATOMIC_SEQ_CST);
19 : :
20 [ + + ]: 3602 : while(updated_current_bytes > observed_peak)
21 : : {
22 [ + - ]: 709 : if(__atomic_compare_exchange_n(
23 : : &telemetry.peak_heap_bytes,
24 : : &observed_peak,
25 : : updated_current_bytes,
26 : : false,
27 : : __ATOMIC_SEQ_CST,
28 : : __ATOMIC_SEQ_CST))
29 : : {
30 : 709 : break;
31 : : }
32 : : }
33 : 3602 : }
34 : :
35 : : /**
36 : : * @brief Track the maximum alignment overhead observed at runtime.
37 : : *
38 : : * @param updated_current_overhead Current alignment padding consumption in bytes.
39 : : */
40 : 3683 : static void telemetry_update_alignment_peak(const size_t updated_current_overhead)
41 : : {
42 : 3683 : size_t observed_peak = __atomic_load_n(&telemetry.peak_alignment_overhead_bytes,__ATOMIC_SEQ_CST);
43 : :
44 [ + + ]: 3683 : while(updated_current_overhead > observed_peak)
45 : : {
46 [ + - ]: 592 : if(__atomic_compare_exchange_n(
47 : : &telemetry.peak_alignment_overhead_bytes,
48 : : &observed_peak,
49 : : updated_current_overhead,
50 : : false,
51 : : __ATOMIC_SEQ_CST,
52 : : __ATOMIC_SEQ_CST))
53 : : {
54 : 592 : break;
55 : : }
56 : : }
57 : 3683 : }
58 : :
59 : : /**
60 : : * @brief Record the highest number of simultaneously active descriptors.
61 : : *
62 : : * @param updated_active_descriptors Current count of active descriptors.
63 : : */
64 : 3574 : static void telemetry_update_active_peak(const size_t updated_active_descriptors)
65 : : {
66 : 3574 : size_t observed_peak = __atomic_load_n(&telemetry.peak_active_descriptors,__ATOMIC_SEQ_CST);
67 : :
68 [ + + ]: 3574 : while(updated_active_descriptors > observed_peak)
69 : : {
70 [ + - ]: 575 : if(__atomic_compare_exchange_n(
71 : : &telemetry.peak_active_descriptors,
72 : : &observed_peak,
73 : : updated_active_descriptors,
74 : : false,
75 : : __ATOMIC_SEQ_CST,
76 : : __ATOMIC_SEQ_CST))
77 : : {
78 : 575 : break;
79 : : }
80 : : }
81 : 3574 : }
82 : :
83 : 1016 : void telemetry_realloc_optimized_counter(void)
84 : : {
85 : 1016 : __atomic_fetch_add(&telemetry.optimized_resizes_counter,1,__ATOMIC_SEQ_CST);
86 : 1016 : }
87 : :
88 : 3574 : void telemetry_new_allocations_counter(void)
89 : : {
90 : 3574 : __atomic_fetch_add(&telemetry.fresh_allocations_counter,1,__ATOMIC_SEQ_CST);
91 : 3574 : }
92 : :
93 : 382 : void telemetry_new_callocations_counter(void)
94 : : {
95 : 382 : __atomic_fetch_add(&telemetry.zero_initialized_allocations_counter,1,__ATOMIC_SEQ_CST);
96 : 382 : }
97 : :
98 : 29 : void telemetry_aligned_reallocations_counter(void)
99 : : {
100 : 29 : __atomic_fetch_add(&telemetry.heap_reallocations_counter,1,__ATOMIC_SEQ_CST);
101 : : #if ROUGH_DEBUG
102 : : printf("telemetry.heap_reallocations_counter: %zu\n",telemetry.heap_reallocations_counter);
103 : : #endif
104 : 29 : }
105 : :
106 : 31 : void telemetry_realloc_noop_counter(void)
107 : : {
108 : 31 : __atomic_fetch_add(&telemetry.exact_size_resizes_counter,1,__ATOMIC_SEQ_CST);
109 : : #if ROUGH_DEBUG
110 : : printf("telemetry.exact_size_resizes_counter: %zu\n",telemetry.exact_size_resizes_counter);
111 : : #endif
112 : 31 : }
113 : :
114 : 3574 : void telemetry_free_counter(void)
115 : : {
116 : 3574 : __atomic_fetch_add(&telemetry.release_operations_counter,1,__ATOMIC_SEQ_CST);
117 : : #if ROUGH_DEBUG
118 : : printf("telemetry.release_operations_counter: %zu\n",telemetry.release_operations_counter);
119 : : #endif
120 : 3574 : }
121 : :
122 : 3575 : void telemetry_free_total_bytes(const size_t amount_of_bytes)
123 : : {
124 : 3575 : __atomic_fetch_add(&telemetry.total_heap_bytes_released,amount_of_bytes,__ATOMIC_SEQ_CST);
125 : : #if ROUGH_DEBUG
126 : : printf("telemetry.total_heap_bytes_released: %zu\n",telemetry.total_heap_bytes_released);
127 : : #endif
128 : 3575 : }
129 : :
130 : 1 : void telemetry_release_unused_operation(void)
131 : : {
132 : 1 : __atomic_fetch_add(&telemetry.release_unused_operations_counter,1,__ATOMIC_SEQ_CST);
133 : 1 : }
134 : :
135 : 1 : void telemetry_release_unused_bytes(const size_t amount_of_bytes)
136 : : {
137 [ - + ]: 1 : if(amount_of_bytes == 0)
138 : : {
139 : 0 : return;
140 : : }
141 : :
142 : 1 : __atomic_fetch_add(&telemetry.release_unused_bytes_total,amount_of_bytes,__ATOMIC_SEQ_CST);
143 : : }
144 : :
145 : 3602 : void telemetry_add(const size_t amount_of_bytes)
146 : : {
147 : 3602 : const size_t updated_current_bytes = __atomic_add_fetch(
148 : : &telemetry.current_heap_bytes,
149 : : amount_of_bytes,
150 : : __ATOMIC_SEQ_CST);
151 : :
152 : 3602 : __atomic_fetch_add(&telemetry.total_heap_bytes_acquired,amount_of_bytes,__ATOMIC_SEQ_CST);
153 : 3602 : telemetry_update_peak(updated_current_bytes);
154 : :
155 : : #if ROUGH_DEBUG
156 : : printf("+%zu\n",amount_of_bytes);
157 : : #endif
158 : 3602 : }
159 : :
160 : 4412 : void telemetry_effective_add(const size_t amount_of_bytes)
161 : : {
162 : 4412 : __atomic_fetch_add(&telemetry.total_payload_bytes_acquired,amount_of_bytes,__ATOMIC_SEQ_CST);
163 : 4412 : __atomic_add_fetch(&telemetry.current_payload_bytes,amount_of_bytes,__ATOMIC_SEQ_CST);
164 : :
165 : : #if ROUGH_DEBUG
166 : : printf("+%zu\n",amount_of_bytes);
167 : : #endif
168 : 4412 : }
169 : :
170 : 3575 : void telemetry_reduce(const size_t amount_of_bytes)
171 : : {
172 : 3575 : __atomic_sub_fetch(&telemetry.current_heap_bytes,amount_of_bytes,__ATOMIC_SEQ_CST);
173 : : #if ROUGH_DEBUG
174 : : printf("-%zu\n",amount_of_bytes);
175 : : #endif
176 : 3575 : }
177 : :
178 : 3781 : void telemetry_effective_reduce(const size_t amount_of_bytes)
179 : : {
180 : 3781 : __atomic_sub_fetch(&telemetry.current_payload_bytes,amount_of_bytes,__ATOMIC_SEQ_CST);
181 : : #if ROUGH_DEBUG
182 : : printf("-%zu\n",amount_of_bytes);
183 : : #endif
184 : 3781 : }
185 : :
186 : 0 : void telemetry_allocation_failure(void)
187 : : {
188 : 0 : __atomic_fetch_add(&telemetry.heap_allocation_failures_counter,1,__ATOMIC_SEQ_CST);
189 : 0 : }
190 : :
191 : 0 : void telemetry_reallocation_failure(void)
192 : : {
193 : 0 : __atomic_fetch_add(&telemetry.heap_reallocation_failures_counter,1,__ATOMIC_SEQ_CST);
194 : 0 : }
195 : :
196 : 3683 : void telemetry_alignment_overhead_add(const size_t amount_of_bytes)
197 : : {
198 [ - + ]: 3683 : if(amount_of_bytes == 0)
199 : : {
200 : 0 : return;
201 : : }
202 : :
203 : 3683 : const size_t updated_current_overhead = __atomic_add_fetch(
204 : : &telemetry.current_alignment_overhead_bytes,
205 : : amount_of_bytes,
206 : : __ATOMIC_SEQ_CST);
207 : :
208 : 3683 : __atomic_fetch_add(&telemetry.total_alignment_overhead_bytes,amount_of_bytes,__ATOMIC_SEQ_CST);
209 : 3683 : telemetry_update_alignment_peak(updated_current_overhead);
210 : : }
211 : :
212 : 4275 : void telemetry_alignment_overhead_reduce(const size_t amount_of_bytes)
213 : : {
214 [ - + ]: 4275 : if(amount_of_bytes == 0)
215 : : {
216 : 0 : return;
217 : : }
218 : :
219 : 4275 : size_t current_overhead = __atomic_load_n(&telemetry.current_alignment_overhead_bytes,__ATOMIC_SEQ_CST);
220 : :
221 [ + + ]: 4275 : if(amount_of_bytes >= current_overhead)
222 : : {
223 : 808 : __atomic_store_n(&telemetry.current_alignment_overhead_bytes,0,__ATOMIC_SEQ_CST);
224 : : } else {
225 : 3467 : __atomic_sub_fetch(&telemetry.current_alignment_overhead_bytes,amount_of_bytes,__ATOMIC_SEQ_CST);
226 : : }
227 : : }
228 : :
229 : 31 : void telemetry_noop_resize_event(void)
230 : : {
231 : 31 : const size_t updated_streak = __atomic_add_fetch(
232 : : &telemetry.noop_resize_streak_current,
233 : : 1,
234 : : __ATOMIC_SEQ_CST);
235 : :
236 : 31 : size_t observed_peak = __atomic_load_n(&telemetry.noop_resize_streak_peak,__ATOMIC_SEQ_CST);
237 : :
238 [ + + ]: 31 : while(updated_streak > observed_peak)
239 : : {
240 [ + - ]: 2 : if(__atomic_compare_exchange_n(
241 : : &telemetry.noop_resize_streak_peak,
242 : : &observed_peak,
243 : : updated_streak,
244 : : false,
245 : : __ATOMIC_SEQ_CST,
246 : : __ATOMIC_SEQ_CST))
247 : : {
248 : 2 : break;
249 : : }
250 : : }
251 : 31 : }
252 : :
253 : 4619 : void telemetry_reset_noop_streak(void)
254 : : {
255 : 4619 : __atomic_store_n(&telemetry.noop_resize_streak_current,0,__ATOMIC_SEQ_CST);
256 : 4619 : }
257 : :
258 : 1600 : void telemetry_string_padding_event(void)
259 : : {
260 : 1600 : __atomic_fetch_add(&telemetry.concat_zero_padding_counter,1,__ATOMIC_SEQ_CST);
261 : 1600 : }
262 : :
263 : 3574 : void telemetry_active_descriptor_acquire(void)
264 : : {
265 : 3574 : const size_t updated_active = __atomic_add_fetch(
266 : : &telemetry.active_descriptors,
267 : : 1,
268 : : __ATOMIC_SEQ_CST);
269 : :
270 : 3574 : telemetry_update_active_peak(updated_active);
271 : 3574 : }
272 : :
273 : 3574 : void telemetry_active_descriptor_release(void)
274 : : {
275 : 3574 : size_t current_active = __atomic_load_n(&telemetry.active_descriptors,__ATOMIC_SEQ_CST);
276 : :
277 [ + - ]: 3574 : while(current_active > 0)
278 : : {
279 : 3574 : if(__atomic_compare_exchange_n(
280 : : &telemetry.active_descriptors,
281 : : ¤t_active,
282 [ + - ]: 3574 : current_active - 1,
283 : : false,
284 : : __ATOMIC_SEQ_CST,
285 : : __ATOMIC_SEQ_CST))
286 : : {
287 : 3574 : break;
288 : : }
289 : : }
290 : 3574 : }
291 : :
292 : 0 : void telemetry_overflow_guard_failure(void)
293 : : {
294 : 0 : __atomic_fetch_add(&telemetry.overflow_guard_failures_counter,1,__ATOMIC_SEQ_CST);
295 : 0 : }
296 : :
297 : 1 : void init_telemetry(void)
298 : : {
299 : 1 : memset(&telemetry,0x0,sizeof(Telemetry));
300 : 1 : }
301 : :
302 : 1 : void telemetry_show(void)
303 : : {
304 : : char buf[FORM_OUTPUT_BUFFER_SIZE];
305 : :
306 : 1 : printf("Telemetry: Outstanding heap bytes (expected 0): %s\n",bkbmbgbtbpbeb(telemetry.current_heap_bytes,FULL_VIEW));
307 : 1 : printf("Telemetry: Outstanding payload bytes (expected 0): %s\n",bkbmbgbtbpbeb(telemetry.current_payload_bytes,FULL_VIEW));
308 : 1 : printf("Telemetry: Peak heap footprint: %s\n",bkbmbgbtbpbeb(telemetry.peak_heap_bytes,FULL_VIEW));
309 : 1 : printf("Telemetry: Free operations count: %s\n",form(telemetry.release_operations_counter,buf,sizeof(buf)));
310 : 1 : printf("Telemetry: Bytes released to the OS: %s\n",bkbmbgbtbpbeb(telemetry.total_heap_bytes_released,FULL_VIEW));
311 : 1 : printf("Telemetry: Shrink calls that forced immediate buffer release: %s\n",form(telemetry.release_unused_operations_counter,buf,sizeof(buf)));
312 : 1 : printf("Telemetry: Bytes returned by those forced releases: %s\n",bkbmbgbtbpbeb(telemetry.release_unused_bytes_total,FULL_VIEW));
313 : 1 : printf("Telemetry: Fresh allocation count: %s\n",form(telemetry.fresh_allocations_counter,buf,sizeof(buf)));
314 : 1 : printf("Telemetry: Zero-initialized allocation count: %s\n",form(telemetry.zero_initialized_allocations_counter,buf,sizeof(buf)));
315 : 1 : printf("Telemetry: Optimized resize count: %s\n",form(telemetry.optimized_resizes_counter,buf,sizeof(buf)));
316 : 1 : printf("Telemetry: Realignment resize count: %s\n",form(telemetry.heap_reallocations_counter,buf,sizeof(buf)));
317 : 1 : printf("Telemetry: Total aligned bytes requested: %s\n",bkbmbgbtbpbeb(telemetry.total_heap_bytes_acquired,FULL_VIEW));
318 : 1 : printf("Telemetry: Total payload bytes requested: %s\n",bkbmbgbtbpbeb(telemetry.total_payload_bytes_acquired,FULL_VIEW));
319 : 1 : printf("Telemetry: Exact-size resize count: %s\n",form(telemetry.exact_size_resizes_counter,buf,sizeof(buf)));
320 : 1 : printf("Telemetry: Allocation failures intercepted: %s\n",form(telemetry.heap_allocation_failures_counter,buf,sizeof(buf)));
321 : 1 : printf("Telemetry: Reallocation failures intercepted: %s\n",form(telemetry.heap_reallocation_failures_counter,buf,sizeof(buf)));
322 : 1 : printf("Telemetry: Current alignment overhead: %s\n",bkbmbgbtbpbeb(telemetry.current_alignment_overhead_bytes,FULL_VIEW));
323 : 1 : printf("Telemetry: Peak alignment overhead: %s\n",bkbmbgbtbpbeb(telemetry.peak_alignment_overhead_bytes,FULL_VIEW));
324 : 1 : printf("Telemetry: Total alignment overhead accrued: %s\n",bkbmbgbtbpbeb(telemetry.total_alignment_overhead_bytes,FULL_VIEW));
325 : 1 : printf("Telemetry: Current no-op resize streak: %s\n",form(telemetry.noop_resize_streak_current,buf,sizeof(buf)));
326 : 1 : printf("Telemetry: Longest no-op resize streak: %s\n",form(telemetry.noop_resize_streak_peak,buf,sizeof(buf)));
327 : 1 : printf("Telemetry: String padding injections: %s\n",form(telemetry.concat_zero_padding_counter,buf,sizeof(buf)));
328 : 1 : printf("Telemetry: Active descriptors: %s\n",form(telemetry.active_descriptors,buf,sizeof(buf)));
329 : 1 : printf("Telemetry: Peak active descriptors: %s\n",form(telemetry.peak_active_descriptors,buf,sizeof(buf)));
330 : 1 : printf("Telemetry: Overflow guards triggered: %s\n",form(telemetry.overflow_guard_failures_counter,buf,sizeof(buf)));
331 : 1 : }
|