LCOV - code coverage report
Current view: top level - libs/mem/src - mem_telemetry.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.7 % 137 116
Test Date: 2026-01-12 05:34:38 Functions: 78.6 % 28 22

            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         1294 : static void telemetry_update_peak(const size_t updated_current_bytes)
      17              : {
      18         1294 :         size_t observed_peak = __atomic_load_n(&telemetry.peak_heap_bytes,__ATOMIC_SEQ_CST);
      19              : 
      20         1294 :         while(updated_current_bytes > observed_peak)
      21              :         {
      22          248 :                 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          248 :                         break;
      31              :                 }
      32              :         }
      33         1294 : }
      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         1425 : static void telemetry_update_alignment_peak(const size_t updated_current_overhead)
      41              : {
      42         1425 :         size_t observed_peak = __atomic_load_n(&telemetry.peak_alignment_overhead_bytes,__ATOMIC_SEQ_CST);
      43              : 
      44         1425 :         while(updated_current_overhead > observed_peak)
      45              :         {
      46          159 :                 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          159 :                         break;
      55              :                 }
      56              :         }
      57         1425 : }
      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         1268 : static void telemetry_update_active_peak(const size_t updated_active_descriptors)
      65              : {
      66         1268 :         size_t observed_peak = __atomic_load_n(&telemetry.peak_active_descriptors,__ATOMIC_SEQ_CST);
      67              : 
      68         1268 :         while(updated_active_descriptors > observed_peak)
      69              :         {
      70          158 :                 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          158 :                         break;
      79              :                 }
      80              :         }
      81         1268 : }
      82              : 
      83          748 : void telemetry_realloc_optimized_counter(void)
      84              : {
      85          748 :         __atomic_fetch_add(&telemetry.optimized_resizes_counter,1,__ATOMIC_SEQ_CST);
      86          748 : }
      87              : 
      88         1268 : void telemetry_new_allocations_counter(void)
      89              : {
      90         1268 :         __atomic_fetch_add(&telemetry.fresh_allocations_counter,1,__ATOMIC_SEQ_CST);
      91         1268 : }
      92              : 
      93            1 : void telemetry_new_callocations_counter(void)
      94              : {
      95            1 :         __atomic_fetch_add(&telemetry.zero_initialized_allocations_counter,1,__ATOMIC_SEQ_CST);
      96            1 : }
      97              : 
      98           26 : void telemetry_aligned_reallocations_counter(void)
      99              : {
     100           26 :         __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           26 : }
     105              : 
     106           27 : void telemetry_realloc_noop_counter(void)
     107              : {
     108           27 :         __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           27 : }
     113              : 
     114         1268 : void telemetry_free_counter(void)
     115              : {
     116         1268 :         __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         1268 : }
     121              : 
     122         1268 : void telemetry_free_total_bytes(const size_t amount_of_bytes)
     123              : {
     124         1268 :         __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         1268 : }
     129              : 
     130            0 : void telemetry_release_unused_operation(void)
     131              : {
     132            0 :         __atomic_fetch_add(&telemetry.release_unused_operations_counter,1,__ATOMIC_SEQ_CST);
     133            0 : }
     134              : 
     135            0 : void telemetry_release_unused_bytes(const size_t amount_of_bytes)
     136              : {
     137            0 :         if(amount_of_bytes == 0)
     138              :         {
     139            0 :                 return;
     140              :         }
     141              : 
     142            0 :         __atomic_fetch_add(&telemetry.release_unused_bytes_total,amount_of_bytes,__ATOMIC_SEQ_CST);
     143              : }
     144              : 
     145         1294 : void telemetry_add(const size_t amount_of_bytes)
     146              : {
     147         1294 :         const size_t updated_current_bytes = __atomic_add_fetch(
     148              :                 &telemetry.current_heap_bytes,
     149              :                 amount_of_bytes,
     150              :                 __ATOMIC_SEQ_CST);
     151              : 
     152         1294 :         __atomic_fetch_add(&telemetry.total_heap_bytes_acquired,amount_of_bytes,__ATOMIC_SEQ_CST);
     153         1294 :         telemetry_update_peak(updated_current_bytes);
     154              : 
     155              :         #if ROUGH_DEBUG
     156              :         printf("+%zu\n",amount_of_bytes);
     157              :         #endif
     158         1294 : }
     159              : 
     160         1828 : void telemetry_effective_add(const size_t amount_of_bytes)
     161              : {
     162         1828 :         __atomic_fetch_add(&telemetry.total_payload_bytes_acquired,amount_of_bytes,__ATOMIC_SEQ_CST);
     163         1828 :         __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         1828 : }
     169              : 
     170         1268 : void telemetry_reduce(const size_t amount_of_bytes)
     171              : {
     172         1268 :         __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         1268 : }
     177              : 
     178         1482 : void telemetry_effective_reduce(const size_t amount_of_bytes)
     179              : {
     180         1482 :         __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         1482 : }
     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         1425 : void telemetry_alignment_overhead_add(const size_t amount_of_bytes)
     197              : {
     198         1425 :         if(amount_of_bytes == 0)
     199              :         {
     200            0 :                 return;
     201              :         }
     202              : 
     203         1425 :         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         1425 :         __atomic_fetch_add(&telemetry.total_alignment_overhead_bytes,amount_of_bytes,__ATOMIC_SEQ_CST);
     209         1425 :         telemetry_update_alignment_peak(updated_current_overhead);
     210              : }
     211              : 
     212         1730 : void telemetry_alignment_overhead_reduce(const size_t amount_of_bytes)
     213              : {
     214         1730 :         if(amount_of_bytes == 0)
     215              :         {
     216            0 :                 return;
     217              :         }
     218              : 
     219         1730 :         size_t current_overhead = __atomic_load_n(&telemetry.current_alignment_overhead_bytes,__ATOMIC_SEQ_CST);
     220              : 
     221         1730 :         if(amount_of_bytes >= current_overhead)
     222              :         {
     223          592 :                 __atomic_store_n(&telemetry.current_alignment_overhead_bytes,0,__ATOMIC_SEQ_CST);
     224              :         } else {
     225         1138 :                 __atomic_sub_fetch(&telemetry.current_alignment_overhead_bytes,amount_of_bytes,__ATOMIC_SEQ_CST);
     226              :         }
     227              : }
     228              : 
     229           27 : void telemetry_noop_resize_event(void)
     230              : {
     231           27 :         const size_t updated_streak = __atomic_add_fetch(
     232              :                 &telemetry.noop_resize_streak_current,
     233              :                 1,
     234              :                 __ATOMIC_SEQ_CST);
     235              : 
     236           27 :         size_t observed_peak = __atomic_load_n(&telemetry.noop_resize_streak_peak,__ATOMIC_SEQ_CST);
     237              : 
     238           27 :         while(updated_streak > observed_peak)
     239              :         {
     240            1 :                 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            1 :                         break;
     249              :                 }
     250              :         }
     251           27 : }
     252              : 
     253         2042 : void telemetry_reset_noop_streak(void)
     254              : {
     255         2042 :         __atomic_store_n(&telemetry.noop_resize_streak_current,0,__ATOMIC_SEQ_CST);
     256         2042 : }
     257              : 
     258          651 : void telemetry_string_padding_event(void)
     259              : {
     260          651 :         __atomic_fetch_add(&telemetry.concat_zero_padding_counter,1,__ATOMIC_SEQ_CST);
     261          651 : }
     262              : 
     263         1268 : void telemetry_active_descriptor_acquire(void)
     264              : {
     265         1268 :         const size_t updated_active = __atomic_add_fetch(
     266              :                 &telemetry.active_descriptors,
     267              :                 1,
     268              :                 __ATOMIC_SEQ_CST);
     269              : 
     270         1268 :         telemetry_update_active_peak(updated_active);
     271         1268 : }
     272              : 
     273         1268 : void telemetry_active_descriptor_release(void)
     274              : {
     275         1268 :         size_t current_active = __atomic_load_n(&telemetry.active_descriptors,__ATOMIC_SEQ_CST);
     276              : 
     277         1268 :         while(current_active > 0)
     278              :         {
     279         1268 :                 if(__atomic_compare_exchange_n(
     280              :                         &telemetry.active_descriptors,
     281              :                         &current_active,
     282         1268 :                         current_active - 1,
     283              :                         false,
     284              :                         __ATOMIC_SEQ_CST,
     285              :                         __ATOMIC_SEQ_CST))
     286              :                 {
     287         1268 :                         break;
     288              :                 }
     289              :         }
     290         1268 : }
     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            0 : void init_telemetry(void)
     298              : {
     299            0 :         memset(&telemetry,0x0,sizeof(Telemetry));
     300            0 : }
     301              : 
     302            1 : void telemetry_show(void)
     303              : {
     304            1 :         printf("Telemetry: Outstanding heap bytes (expected 0): %s\n",bkbmbgbtbpbeb(telemetry.current_heap_bytes));
     305            1 :         printf("Telemetry: Outstanding payload bytes (expected 0): %s\n",bkbmbgbtbpbeb(telemetry.current_payload_bytes));
     306            1 :         printf("Telemetry: Peak heap footprint: %s\n",bkbmbgbtbpbeb(telemetry.peak_heap_bytes));
     307            1 :         printf("Telemetry: Free operations count: %s\n",form(telemetry.release_operations_counter));
     308            1 :         printf("Telemetry: Bytes released to the OS: %s\n",bkbmbgbtbpbeb(telemetry.total_heap_bytes_released));
     309            1 :         printf("Telemetry: Shrink calls that forced immediate buffer release: %s\n",form(telemetry.release_unused_operations_counter));
     310            1 :         printf("Telemetry: Bytes returned by those forced releases: %s\n",bkbmbgbtbpbeb(telemetry.release_unused_bytes_total));
     311            1 :         printf("Telemetry: Fresh allocation count: %s\n",form(telemetry.fresh_allocations_counter));
     312            1 :         printf("Telemetry: Zero-initialized allocation count: %s\n",form(telemetry.zero_initialized_allocations_counter));
     313            1 :         printf("Telemetry: Optimized resize count: %s\n",form(telemetry.optimized_resizes_counter));
     314            1 :         printf("Telemetry: Realignment resize count: %s\n",form(telemetry.heap_reallocations_counter));
     315            1 :         printf("Telemetry: Total aligned bytes requested: %s\n",bkbmbgbtbpbeb(telemetry.total_heap_bytes_acquired));
     316            1 :         printf("Telemetry: Total payload bytes requested: %s\n",bkbmbgbtbpbeb(telemetry.total_payload_bytes_acquired));
     317            1 :         printf("Telemetry: Exact-size resize count: %s\n",form(telemetry.exact_size_resizes_counter));
     318            1 :         printf("Telemetry: Allocation failures intercepted: %s\n",form(telemetry.heap_allocation_failures_counter));
     319            1 :         printf("Telemetry: Reallocation failures intercepted: %s\n",form(telemetry.heap_reallocation_failures_counter));
     320            1 :         printf("Telemetry: Current alignment overhead: %s\n",bkbmbgbtbpbeb(telemetry.current_alignment_overhead_bytes));
     321            1 :         printf("Telemetry: Peak alignment overhead: %s\n",bkbmbgbtbpbeb(telemetry.peak_alignment_overhead_bytes));
     322            1 :         printf("Telemetry: Total alignment overhead accrued: %s\n",bkbmbgbtbpbeb(telemetry.total_alignment_overhead_bytes));
     323            1 :         printf("Telemetry: Current no-op resize streak: %s\n",form(telemetry.noop_resize_streak_current));
     324            1 :         printf("Telemetry: Longest no-op resize streak: %s\n",form(telemetry.noop_resize_streak_peak));
     325            1 :         printf("Telemetry: String padding injections: %s\n",form(telemetry.concat_zero_padding_counter));
     326            1 :         printf("Telemetry: Active descriptors: %s\n",form(telemetry.active_descriptors));
     327            1 :         printf("Telemetry: Peak active descriptors: %s\n",form(telemetry.peak_active_descriptors));
     328            1 :         printf("Telemetry: Overflow guards triggered: %s\n",form(telemetry.overflow_guard_failures_counter));
     329            1 : }
        

Generated by: LCOV version 2.0-1