Unify statistic collection:
- For MI_STAT == 0 no allocation stats are collected - For MI_STAT == 1 only aggregated values (across normal, large and huge heaps) are collected - For MI_STAT == 1 separate per-bin collection for normal heap is done as well
This commit is contained in:
parent
00fb89f771
commit
765fc9c0ca
@ -416,6 +416,7 @@ typedef struct mi_stats_s {
|
||||
mi_stat_count_t segments_abandoned;
|
||||
mi_stat_count_t pages_abandoned;
|
||||
mi_stat_count_t threads;
|
||||
mi_stat_count_t normal;
|
||||
mi_stat_count_t huge;
|
||||
mi_stat_count_t giant;
|
||||
mi_stat_count_t malloc;
|
||||
@ -425,6 +426,7 @@ typedef struct mi_stats_s {
|
||||
mi_stat_counter_t commit_calls;
|
||||
mi_stat_counter_t page_no_retire;
|
||||
mi_stat_counter_t searches;
|
||||
mi_stat_counter_t normal_count;
|
||||
mi_stat_counter_t huge_count;
|
||||
mi_stat_counter_t giant_count;
|
||||
#if MI_STAT>1
|
||||
@ -447,6 +449,7 @@ void _mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount);
|
||||
#define mi_stat_counter_increase(stat,amount) (void)0
|
||||
#endif
|
||||
|
||||
#define mi_heap_stat_counter_increase(heap,stat,amount) mi_stat_counter_increase( (heap)->tld->stats.stat, amount)
|
||||
#define mi_heap_stat_increase(heap,stat,amount) mi_stat_increase( (heap)->tld->stats.stat, amount)
|
||||
#define mi_heap_stat_decrease(heap,stat,amount) mi_stat_decrease( (heap)->tld->stats.stat, amount)
|
||||
|
||||
|
18
src/alloc.c
18
src/alloc.c
@ -39,11 +39,15 @@ extern inline void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t siz
|
||||
block->next = 0; // don't leak internal data
|
||||
#endif
|
||||
|
||||
#if (MI_STAT>1)
|
||||
#if (MI_STAT>0)
|
||||
const size_t bsize = mi_page_usable_block_size(page);
|
||||
if (bsize <= MI_LARGE_OBJ_SIZE_MAX) {
|
||||
mi_heap_stat_increase(heap, normal, bsize);
|
||||
mi_heap_stat_counter_increase(heap, normal_count, 1);
|
||||
#if (MI_STAT>1)
|
||||
const size_t bin = _mi_bin(bsize);
|
||||
mi_heap_stat_increase(heap, normal_bins[bin], 1);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -287,14 +291,22 @@ static void mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, co
|
||||
#endif
|
||||
|
||||
// only maintain stats for smaller objects if requested
|
||||
#if (MI_STAT>1)
|
||||
#if (MI_STAT>0)
|
||||
static void mi_stat_free(const mi_page_t* page, const mi_block_t* block) {
|
||||
#if (MI_STAT < 2)
|
||||
UNUSED(block);
|
||||
#endif
|
||||
mi_heap_t* const heap = mi_heap_get_default();
|
||||
const size_t bsize = mi_page_usable_block_size(page);
|
||||
#if (MI_STAT>1)
|
||||
const size_t usize = mi_page_usable_size_of(page, block);
|
||||
const size_t bsize = mi_page_usable_block_size(page);
|
||||
mi_heap_stat_decrease(heap, malloc, usize);
|
||||
#endif
|
||||
if (bsize <= MI_LARGE_OBJ_SIZE_MAX) {
|
||||
mi_heap_stat_decrease(heap, normal, bsize);
|
||||
#if (MI_STAT > 1)
|
||||
mi_heap_stat_decrease(heap, normal_bins[_mi_bin(bsize)], 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
@ -280,11 +280,14 @@ static bool _mi_heap_page_destroy(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_
|
||||
_mi_stat_decrease(&heap->tld->stats.huge, bsize);
|
||||
}
|
||||
}
|
||||
#if (MI_STAT>1)
|
||||
#if (MI_STAT)
|
||||
_mi_page_free_collect(page, false); // update used count
|
||||
const size_t inuse = page->used;
|
||||
if (bsize <= MI_LARGE_OBJ_SIZE_MAX) {
|
||||
mi_heap_stat_decrease(heap, normal, bsize * inuse);
|
||||
#if (MI_STAT>1)
|
||||
mi_heap_stat_decrease(heap, normal_bins[_mi_bin(bsize)], inuse);
|
||||
#endif
|
||||
}
|
||||
mi_heap_stat_decrease(heap, malloc, bsize * inuse); // todo: off for aligned blocks...
|
||||
#endif
|
||||
|
@ -73,8 +73,8 @@ const mi_page_t _mi_page_empty = {
|
||||
MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \
|
||||
MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \
|
||||
MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \
|
||||
MI_STAT_COUNT_NULL(), \
|
||||
{ 0, 0 }, { 0, 0 }, { 0, 0 }, \
|
||||
MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \
|
||||
{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
|
||||
{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } \
|
||||
MI_STAT_COUNT_END_NULL()
|
||||
|
||||
|
20
src/stats.c
20
src/stats.c
@ -103,6 +103,7 @@ static void mi_stats_add(mi_stats_t* stats, const mi_stats_t* src) {
|
||||
|
||||
mi_stat_add(&stats->malloc, &src->malloc, 1);
|
||||
mi_stat_add(&stats->segments_cache, &src->segments_cache, 1);
|
||||
mi_stat_add(&stats->normal, &src->normal, 1);
|
||||
mi_stat_add(&stats->huge, &src->huge, 1);
|
||||
mi_stat_add(&stats->giant, &src->giant, 1);
|
||||
|
||||
@ -112,6 +113,7 @@ static void mi_stats_add(mi_stats_t* stats, const mi_stats_t* src) {
|
||||
|
||||
mi_stat_counter_add(&stats->page_no_retire, &src->page_no_retire, 1);
|
||||
mi_stat_counter_add(&stats->searches, &src->searches, 1);
|
||||
mi_stat_counter_add(&stats->normal_count, &src->normal_count, 1);
|
||||
mi_stat_counter_add(&stats->huge_count, &src->huge_count, 1);
|
||||
mi_stat_counter_add(&stats->giant_count, &src->giant_count, 1);
|
||||
#if MI_STAT>1
|
||||
@ -219,7 +221,7 @@ static void mi_print_header(mi_output_fun* out, void* arg ) {
|
||||
}
|
||||
|
||||
#if MI_STAT>1
|
||||
static void mi_stats_print_bins(mi_stat_count_t* all, const mi_stat_count_t* bins, size_t max, const char* fmt, mi_output_fun* out, void* arg) {
|
||||
static void mi_stats_print_bins(const mi_stat_count_t* bins, size_t max, const char* fmt, mi_output_fun* out, void* arg) {
|
||||
bool found = false;
|
||||
char buf[64];
|
||||
for (size_t i = 0; i <= max; i++) {
|
||||
@ -227,12 +229,9 @@ static void mi_stats_print_bins(mi_stat_count_t* all, const mi_stat_count_t* bin
|
||||
found = true;
|
||||
int64_t unit = _mi_bin_size((uint8_t)i);
|
||||
snprintf(buf, 64, "%s %3lu", fmt, (long)i);
|
||||
mi_stat_add(all, &bins[i], unit);
|
||||
mi_stat_print(&bins[i], buf, unit, out, arg);
|
||||
}
|
||||
}
|
||||
//snprintf(buf, 64, "%s all", fmt);
|
||||
//mi_stat_print(all, buf, 1);
|
||||
if (found) {
|
||||
_mi_fprintf(out, arg, "\n");
|
||||
mi_print_header(out, arg);
|
||||
@ -289,16 +288,21 @@ static void _mi_stats_print(mi_stats_t* stats, mi_output_fun* out0, void* arg0)
|
||||
// and print using that
|
||||
mi_print_header(out,arg);
|
||||
#if MI_STAT>1
|
||||
mi_stat_count_t normal = { 0,0,0,0 };
|
||||
mi_stats_print_bins(&normal, stats->normal_bins, MI_BIN_HUGE, "normal",out,arg);
|
||||
mi_stat_print(&normal, "normal", 1, out, arg);
|
||||
mi_stats_print_bins(stats->normal_bins, MI_BIN_HUGE, "normal",out,arg);
|
||||
#endif
|
||||
#if MI_STAT
|
||||
mi_stat_print(&stats->normal, "normal", (stats->normal_count.count == 0 ? 1 : -(stats->normal.allocated / stats->normal_count.count)), out, arg);
|
||||
mi_stat_print(&stats->huge, "huge", (stats->huge_count.count == 0 ? 1 : -(stats->huge.allocated / stats->huge_count.count)), out, arg);
|
||||
mi_stat_print(&stats->giant, "giant", (stats->giant_count.count == 0 ? 1 : -(stats->giant.allocated / stats->giant_count.count)), out, arg);
|
||||
mi_stat_count_t total = { 0,0,0,0 };
|
||||
mi_stat_add(&total, &normal, 1);
|
||||
mi_stat_add(&total, &stats->normal, 1);
|
||||
mi_stat_add(&total, &stats->huge, 1);
|
||||
mi_stat_add(&total, &stats->giant, 1);
|
||||
mi_stat_print(&total, "total", 1, out, arg);
|
||||
#endif
|
||||
#if MI_STAT>1
|
||||
mi_stat_print(&stats->malloc, "malloc total", 1, out, arg);
|
||||
|
||||
_mi_fprintf(out, arg, "malloc requested: ");
|
||||
mi_print_amount(stats->malloc.allocated, 1, out, arg);
|
||||
_mi_fprintf(out, arg, "\n\n");
|
||||
|
Loading…
Reference in New Issue
Block a user