@@ -46,6 +46,16 @@ void __mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount) {
4646 stat -> total += amount ;
4747}
4848
49+ void __mi_stat_average_increase_mt (mi_stat_average_t * stat , size_t amount ) {
50+ mi_atomic_addi64_relaxed ( & stat -> count , (int64_t )1 );
51+ mi_atomic_addi64_relaxed ( & stat -> total , (int64_t )amount );
52+ }
53+
54+ void __mi_stat_average_increase (mi_stat_average_t * stat , size_t amount ) {
55+ stat -> count ++ ;
56+ stat -> total += amount ;
57+ }
58+
4959void __mi_stat_increase_mt (mi_stat_count_t * stat , size_t amount ) {
5060 mi_stat_update_mt (stat , (int64_t )amount );
5161}
@@ -111,8 +121,15 @@ static void mi_stat_counter_add_mt(mi_stat_counter_t* stat, const mi_stat_counte
111121 mi_atomic_void_addi64_relaxed (& stat -> total , & src -> total );
112122}
113123
124+ static void mi_stat_average_add_mt (mi_stat_average_t * stat , const mi_stat_average_t * src ) {
125+ if (stat == src ) return ;
126+ mi_atomic_void_addi64_relaxed (& stat -> count , & src -> count );
127+ mi_atomic_void_addi64_relaxed (& stat -> total , & src -> total );
128+ }
129+
114130#define MI_STAT_COUNT (stat ) mi_stat_count_add_mt(&stats->stat, &src->stat);
115131#define MI_STAT_COUNTER (stat ) mi_stat_counter_add_mt(&stats->stat, &src->stat);
132+ #define MI_STAT_AVERAGE (stat ) mi_stat_average_add_mt(&stats->stat, &src->stat);
116133
117134// must be thread safe as it is called from stats_merge
118135static void mi_stats_add (mi_stats_t * stats , const mi_stats_t * src ) {
@@ -133,6 +150,7 @@ static void mi_stats_add(mi_stats_t* stats, const mi_stats_t* src) {
133150
134151#undef MI_STAT_COUNT
135152#undef MI_STAT_COUNTER
153+ #undef MI_STAT_AVERAGE
136154
137155/* -----------------------------------------------------------
138156 Display statistics
@@ -225,12 +243,6 @@ static void mi_stat_print(const mi_stat_count_t* stat, const char* msg, int64_t
225243 mi_stat_print_ex (stat , msg , unit , out , arg , NULL );
226244}
227245
228- static void mi_stat_peak_print (const mi_stat_count_t * stat , const char * msg , int64_t unit , mi_output_fun * out , void * arg ) {
229- _mi_fprintf (out , arg , "%10s:" , msg );
230- mi_print_amount (stat -> peak , unit , out , arg );
231- _mi_fprintf (out , arg , "\n" );
232- }
233-
234246#if MI_STAT > 1
235247static void mi_stat_total_print (const mi_stat_count_t * stat , const char * msg , int64_t unit , mi_output_fun * out , void * arg ) {
236248 _mi_fprintf (out , arg , "%10s:" , msg );
@@ -246,15 +258,13 @@ static void mi_stat_counter_print(const mi_stat_counter_t* stat, const char* msg
246258 _mi_fprintf (out , arg , "\n" );
247259}
248260
249-
250- static void mi_stat_counter_print_avg (const mi_stat_counter_t * stat , const char * msg , mi_output_fun * out , void * arg ) {
251- const int64_t avg_tens = (stat -> total == 0 ? 0 : (stat -> total * 10 / stat -> total ));
261+ static void mi_stat_average_print (const mi_stat_average_t * stat , const char * msg , mi_output_fun * out , void * arg ) {
262+ const int64_t avg_tens = (stat -> count == 0 ? 0 : (stat -> total * 10 / stat -> count ));
252263 const long avg_whole = (long )(avg_tens /10 );
253264 const long avg_frac1 = (long )(avg_tens %10 );
254265 _mi_fprintf (out , arg , "%10s: %5ld.%ld avg\n" , msg , avg_whole , avg_frac1 );
255266}
256267
257-
258268static void mi_print_header (mi_output_fun * out , void * arg ) {
259269 _mi_fprintf (out , arg , "%10s: %11s %11s %11s %11s %11s\n" , "heap stats" , "peak " , "total " , "current " , "block " , "total# " );
260270}
@@ -341,8 +351,8 @@ void _mi_stats_print(mi_stats_t* stats, mi_output_fun* out0, void* arg0) mi_attr
341351 #endif
342352 mi_stat_print_ex (& stats -> reserved , "reserved" , 1 , out , arg , "" );
343353 mi_stat_print_ex (& stats -> committed , "committed" , 1 , out , arg , "" );
344- mi_stat_peak_print (& stats -> reset , "reset" , 1 , out , arg );
345- mi_stat_peak_print (& stats -> purged , "purged" , 1 , out , arg );
354+ mi_stat_counter_print (& stats -> reset , "reset" , out , arg );
355+ mi_stat_counter_print (& stats -> purged , "purged" , out , arg );
346356 mi_stat_print_ex (& stats -> page_committed , "touched" , 1 , out , arg , "" );
347357 // mi_stat_print(&stats->segments, "segments", -1, out, arg);
348358 // mi_stat_print(&stats->segments_abandoned, "-abandoned", -1, out, arg);
@@ -365,7 +375,7 @@ void _mi_stats_print(mi_stats_t* stats, mi_output_fun* out0, void* arg0) mi_attr
365375 mi_stat_counter_print (& stats -> purge_calls , "purges" , out , arg );
366376 mi_stat_counter_print (& stats -> malloc_guarded_count , "guarded" , out , arg );
367377 mi_stat_print (& stats -> threads , "threads" , -1 , out , arg );
368- mi_stat_counter_print_avg (& stats -> page_searches , "searches" , out , arg );
378+ mi_stat_average_print (& stats -> page_searches , "searches" , out , arg );
369379 _mi_fprintf (out , arg , "%10s: %5i\n" , "numa nodes" , _mi_os_numa_node_count ());
370380
371381 size_t elapsed ;
@@ -619,8 +629,16 @@ static void mi_heap_buf_print_counter_value(mi_heap_buf_t* hbuf, const char* nam
619629 mi_heap_buf_print_value (hbuf , name , stat -> total );
620630}
621631
632+ static void mi_heap_buf_print_average_value (mi_heap_buf_t * hbuf , const char * name , mi_stat_average_t * stat ) {
633+ char buf [128 ];
634+ _mi_snprintf (buf , 128 , " \"%s\": { \"count\": %lld, \"total\": %lld },\n" , name , stat -> count , stat -> total );
635+ buf [127 ] = 0 ;
636+ mi_heap_buf_print (hbuf , buf );
637+ }
638+
622639#define MI_STAT_COUNT (stat ) mi_heap_buf_print_count_value(&hbuf, #stat, &stats->stat);
623640#define MI_STAT_COUNTER (stat ) mi_heap_buf_print_counter_value(&hbuf, #stat, &stats->stat);
641+ #define MI_STAT_AVERAGE (stat ) mi_heap_buf_print_average_value(&hbuf, #stat, &stats->stat);
624642
625643char * mi_stats_get_json (size_t output_size , char * output_buf ) mi_attr_noexcept {
626644 mi_stats_merge ();
0 commit comments