mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-06 15:29:31 +03:00
merge from dev; lean stats
This commit is contained in:
commit
ec92690117
6 changed files with 152 additions and 142 deletions
|
@ -83,6 +83,19 @@ else()
|
|||
set(mi_defines "")
|
||||
endif()
|
||||
|
||||
# pass git revision as a define
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/.git/index")
|
||||
find_package(Git)
|
||||
if(GIT_FOUND)
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} "describe" OUTPUT_VARIABLE mi_git_describe RESULT_VARIABLE mi_git_res ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(mi_git_res EQUAL "0")
|
||||
list(APPEND mi_defines "MI_GIT_DESCRIBE=${mi_git_describe}")
|
||||
# add to dependencies so we rebuild if the git head commit changes
|
||||
set_property(GLOBAL APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/.git/index")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Convenience: set default build type and compiler depending on the build directory
|
||||
# -----------------------------------------------------------------------------
|
||||
|
@ -514,6 +527,7 @@ else()
|
|||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Install and output names
|
||||
# -----------------------------------------------------------------------------
|
||||
|
@ -544,6 +558,7 @@ if(MI_TRACK_ASAN)
|
|||
set(mi_libname "${mi_libname}-asan")
|
||||
endif()
|
||||
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LC)
|
||||
list(APPEND mi_defines "MI_CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE_LC}") #todo: multi-config project needs $<CONFIG> ?
|
||||
if(NOT(CMAKE_BUILD_TYPE_LC MATCHES "^(release|relwithdebinfo|minsizerel|none)$"))
|
||||
set(mi_libname "${mi_libname}-${CMAKE_BUILD_TYPE_LC}") #append build type (e.g. -debug) if not a release version
|
||||
endif()
|
||||
|
|
|
@ -459,15 +459,13 @@ struct mi_heap_s {
|
|||
#endif
|
||||
|
||||
typedef struct mi_stat_count_s {
|
||||
int64_t allocated;
|
||||
int64_t freed;
|
||||
int64_t total;
|
||||
int64_t peak;
|
||||
int64_t current;
|
||||
} mi_stat_count_t;
|
||||
|
||||
typedef struct mi_stat_counter_s {
|
||||
int64_t total;
|
||||
int64_t count;
|
||||
} mi_stat_counter_t;
|
||||
|
||||
typedef struct mi_stats_s {
|
||||
|
@ -510,11 +508,13 @@ void __mi_stat_increase(mi_stat_count_t* stat, size_t amount);
|
|||
void __mi_stat_decrease(mi_stat_count_t* stat, size_t amount);
|
||||
void __mi_stat_increase_mt(mi_stat_count_t* stat, size_t amount);
|
||||
void __mi_stat_decrease_mt(mi_stat_count_t* stat, size_t amount);
|
||||
// adjust stat in special cases to compensate for double counting
|
||||
void __mi_stat_adjust_increase(mi_stat_count_t* stat, size_t amount, bool on_alloc);
|
||||
void __mi_stat_adjust_decrease(mi_stat_count_t* stat, size_t amount, bool on_free);
|
||||
void __mi_stat_adjust_increase_mt(mi_stat_count_t* stat, size_t amount, bool on_alloc);
|
||||
void __mi_stat_adjust_decrease_mt(mi_stat_count_t* stat, size_t amount, bool on_free);
|
||||
|
||||
// adjust stat in special cases to compensate for double counting (and does not adjust peak values and can decrease the total)
|
||||
void __mi_stat_adjust_increase(mi_stat_count_t* stat, size_t amount);
|
||||
void __mi_stat_adjust_decrease(mi_stat_count_t* stat, size_t amount);
|
||||
void __mi_stat_adjust_increase_mt(mi_stat_count_t* stat, size_t amount);
|
||||
void __mi_stat_adjust_decrease_mt(mi_stat_count_t* stat, size_t amount);
|
||||
|
||||
// counters can just be increased
|
||||
void __mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount);
|
||||
void __mi_stat_counter_increase_mt(mi_stat_counter_t* stat, size_t amount);
|
||||
|
@ -526,8 +526,6 @@ void __mi_stat_counter_increase_mt(mi_stat_counter_t* stat, size_t amount);
|
|||
#define mi_debug_stat_increase_mt(stat,amount) __mi_stat_increase_mt( &(stat), amount)
|
||||
#define mi_debug_stat_decrease_mt(stat,amount) __mi_stat_decrease_mt( &(stat), amount)
|
||||
#define mi_debug_stat_counter_increase_mt(stat,amount) __mi_stat_counter_increase_mt( &(stat), amount)
|
||||
#define mi_debug_stat_adjust_increase_mt(stat,amnt,b) __mi_stat_adjust_increase_mt( &(stat), amnt, b)
|
||||
#define mi_debug_stat_adjust_decrease_mt(stat,amnt,b) __mi_stat_adjust_decrease_mt( &(stat), amnt, b)
|
||||
#else
|
||||
#define mi_debug_stat_increase(stat,amount) ((void)0)
|
||||
#define mi_debug_stat_decrease(stat,amount) ((void)0)
|
||||
|
@ -535,22 +533,19 @@ void __mi_stat_counter_increase_mt(mi_stat_counter_t* stat, size_t amount);
|
|||
#define mi_debug_stat_increase_mt(stat,amount) ((void)0)
|
||||
#define mi_debug_stat_decrease_mt(stat,amount) ((void)0)
|
||||
#define mi_debug_stat_counter_increase_mt(stat,amount) ((void)0)
|
||||
#define mi_debug_stat_adjust_increase(stat,amnt,b) ((void)0)
|
||||
#define mi_debug_stat_adjust_decrease(stat,amnt,b) ((void)0)
|
||||
#endif
|
||||
|
||||
#define mi_subproc_stat_counter_increase(subproc,stat,amount) __mi_stat_counter_increase_mt( &(subproc)->stats.stat, amount)
|
||||
#define mi_subproc_stat_increase(subproc,stat,amount) __mi_stat_increase_mt( &(subproc)->stats.stat, amount)
|
||||
#define mi_subproc_stat_decrease(subproc,stat,amount) __mi_stat_decrease_mt( &(subproc)->stats.stat, amount)
|
||||
#define mi_subproc_stat_adjust_increase(subproc,stat,amnt,b) __mi_stat_adjust_increase_mt( &(subproc)->stats.stat, amnt, b)
|
||||
#define mi_subproc_stat_adjust_decrease(subproc,stat,amnt,b) __mi_stat_adjust_decrease_mt( &(subproc)->stats.stat, amnt, b)
|
||||
#define mi_subproc_stat_adjust_increase(subproc,stat,amnt) __mi_stat_adjust_increase_mt( &(subproc)->stats.stat, amnt)
|
||||
#define mi_subproc_stat_adjust_decrease(subproc,stat,amnt) __mi_stat_adjust_decrease_mt( &(subproc)->stats.stat, amnt)
|
||||
|
||||
#define mi_tld_stat_counter_increase(tld,stat,amount) __mi_stat_counter_increase( &(tld)->stats.stat, amount)
|
||||
#define mi_tld_stat_increase(tld,stat,amount) __mi_stat_increase( &(tld)->stats.stat, amount)
|
||||
#define mi_tld_stat_decrease(tld,stat,amount) __mi_stat_decrease( &(tld)->stats.stat, amount)
|
||||
#define mi_tld_stat_adjust_increase(tld,stat,amnt,b) __mi_stat_adjust_increase( &(tld)->stats.stat, amnt, b)
|
||||
#define mi_tld_stat_adjust_decrease(tld,stat,amnt,b) __mi_stat_adjust_decrease( &(tld)->stats.stat, amnt, b)
|
||||
|
||||
#define mi_tld_stat_adjust_increase(tld,stat,amnt) __mi_stat_adjust_increase( &(tld)->stats.stat, amnt)
|
||||
#define mi_tld_stat_adjust_decrease(tld,stat,amnt) __mi_stat_adjust_decrease( &(tld)->stats.stat, amnt)
|
||||
|
||||
#define mi_os_stat_counter_increase(stat,amount) mi_subproc_stat_counter_increase(_mi_subproc(),stat,amount)
|
||||
#define mi_os_stat_increase(stat,amount) mi_subproc_stat_increase(_mi_subproc(),stat,amount)
|
||||
|
|
16
src/arena.c
16
src/arena.c
|
@ -209,10 +209,6 @@ static mi_decl_noinline void* mi_arena_try_alloc_at(
|
|||
// we set the bits first since we own these slices (they are no longer free)
|
||||
size_t already_committed_count = 0;
|
||||
mi_bitmap_setN(arena->slices_committed, slice_index, slice_count, &already_committed_count);
|
||||
// adjust the stats so we don't double count the commits
|
||||
//if (already_committed_count > 0) {
|
||||
// mi_subproc_stat_adjust_decrease(arena->subproc, committed, mi_size_of_slices(already_committed_count), true /* on alloc */);
|
||||
//}
|
||||
// now actually commit
|
||||
bool commit_zero = false;
|
||||
if (!_mi_os_commit_ex(p, mi_size_of_slices(slice_count), &commit_zero, mi_size_of_slices(slice_count - already_committed_count))) {
|
||||
|
@ -315,20 +311,18 @@ static bool mi_arena_reserve(mi_subproc_t* subproc, size_t req_size, bool allow_
|
|||
// on an OS with overcommit (Linux) we don't count the commit yet as it is on-demand. Once a slice
|
||||
// is actually allocated for the first time it will be counted.
|
||||
const bool adjust = (overcommit && arena_commit);
|
||||
if (adjust) {
|
||||
mi_subproc_stat_adjust_decrease( subproc, committed, arena_reserve, true /* on alloc */);
|
||||
}
|
||||
if (adjust) { mi_subproc_stat_adjust_decrease( subproc, committed, arena_reserve); }
|
||||
// and try to reserve the arena
|
||||
int err = mi_reserve_os_memory_ex2(subproc, arena_reserve, arena_commit, allow_large, false /* exclusive? */, arena_id);
|
||||
if (err != 0) {
|
||||
if (adjust) { mi_subproc_stat_adjust_increase( subproc, committed, arena_reserve, true); } // roll back
|
||||
if (adjust) { mi_subproc_stat_adjust_increase( subproc, committed, arena_reserve); } // roll back
|
||||
// failed, try a smaller size?
|
||||
const size_t small_arena_reserve = (MI_SIZE_BITS == 32 ? 128*MI_MiB : 1*MI_GiB);
|
||||
if (adjust) { mi_subproc_stat_adjust_decrease( subproc, committed, arena_reserve, true); }
|
||||
if (adjust) { mi_subproc_stat_adjust_decrease( subproc, committed, arena_reserve); }
|
||||
if (arena_reserve > small_arena_reserve) {
|
||||
// try again
|
||||
err = mi_reserve_os_memory_ex(small_arena_reserve, arena_commit, allow_large, false /* exclusive? */, arena_id);
|
||||
if (err != 0 && adjust) { mi_subproc_stat_adjust_increase( subproc, committed, arena_reserve, true); } // roll back
|
||||
if (err != 0 && adjust) { mi_subproc_stat_adjust_increase( subproc, committed, arena_reserve); } // roll back
|
||||
}
|
||||
}
|
||||
return (err==0);
|
||||
|
@ -918,7 +912,7 @@ bool _mi_arenas_page_try_reabandon_to_mapped(mi_page_t* page) {
|
|||
else {
|
||||
mi_tld_t* tld = _mi_thread_tld();
|
||||
mi_tld_stat_counter_increase( tld, pages_reabandon_full, 1);
|
||||
mi_tld_stat_adjust_decrease( tld, pages_abandoned, 1, true /* on alloc */); // adjust as we are not abandoning fresh
|
||||
mi_tld_stat_adjust_decrease( tld, pages_abandoned, 1); // adjust as we are not abandoning fresh
|
||||
_mi_arenas_page_abandon(page,tld);
|
||||
return true;
|
||||
}
|
||||
|
|
12
src/init.c
12
src/init.c
|
@ -65,11 +65,11 @@ const mi_page_t _mi_page_empty = {
|
|||
QNULL(MI_LARGE_MAX_OBJ_WSIZE + 1 /* 655360, Huge queue */), \
|
||||
QNULL(MI_LARGE_MAX_OBJ_WSIZE + 2) /* Full queue */ }
|
||||
|
||||
#define MI_STAT_COUNT_NULL() {0,0,0,0}
|
||||
#define MI_STAT_COUNT_NULL() {0,0,0}
|
||||
|
||||
// Empty statistics
|
||||
#if MI_STAT>1
|
||||
#define MI_STAT_COUNT_END_NULL() , { MI_STAT_COUNT_NULL(), MI_INIT32(MI_STAT_COUNT_NULL) }
|
||||
#define MI_STAT_COUNT_END_NULL() , { MI_INIT64(MI_STAT_COUNT_NULL), MI_INIT8(MI_STAT_COUNT_NULL), MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL() }
|
||||
#else
|
||||
#define MI_STAT_COUNT_END_NULL()
|
||||
#endif
|
||||
|
@ -81,10 +81,10 @@ 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(), \
|
||||
{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
|
||||
{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
|
||||
{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, \
|
||||
{ 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } \
|
||||
{ 0 }, { 0 }, { 0 }, { 0 }, \
|
||||
{ 0 }, { 0 }, { 0 }, { 0 }, \
|
||||
{ 0 }, { 0 }, { 0 }, { 0 }, \
|
||||
{ 0 }, { 0 }, { 0 }, { 0 } \
|
||||
MI_STAT_COUNT_END_NULL()
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
|
|
@ -189,7 +189,7 @@ void _mi_options_init(void) {
|
|||
mi_add_stderr_output(); // now it safe to use stderr for output
|
||||
for(int i = 0; i < _mi_option_last; i++ ) {
|
||||
mi_option_t option = (mi_option_t)i;
|
||||
mi_option_get(option); // initialize
|
||||
long l = mi_option_get(option); MI_UNUSED(l); // initialize
|
||||
}
|
||||
mi_max_error_count = mi_option_get(mi_option_max_errors);
|
||||
mi_max_warning_count = mi_option_get(mi_option_max_warnings);
|
||||
|
@ -204,24 +204,47 @@ void _mi_options_init(void) {
|
|||
mi_options_print();
|
||||
}
|
||||
|
||||
#define mi_stringifyx(str) #str // and stringify
|
||||
#define mi_stringify(str) mi_stringifyx(str) // expand
|
||||
|
||||
void mi_options_print(void) mi_attr_noexcept
|
||||
{
|
||||
// show version
|
||||
const int vermajor = MI_MALLOC_VERSION/100;
|
||||
const int verminor = (MI_MALLOC_VERSION%100)/10;
|
||||
const int verpatch = (MI_MALLOC_VERSION%10);
|
||||
_mi_verbose_message("v%i.%i.%i (built on %s, %s)\n", vermajor, verminor, verpatch, __DATE__, __TIME__);
|
||||
_mi_verbose_message("v%i.%i.%i%s%s (built on %s, %s)\n", vermajor, verminor, verpatch,
|
||||
#if defined(MI_CMAKE_BUILD_TYPE)
|
||||
", " mi_stringify(MI_CMAKE_BUILD_TYPE)
|
||||
#else
|
||||
""
|
||||
#endif
|
||||
,
|
||||
#if defined(MI_GIT_DESCRIBE)
|
||||
", git " mi_stringify(MI_GIT_DESCRIBE)
|
||||
#else
|
||||
""
|
||||
#endif
|
||||
, __DATE__, __TIME__);
|
||||
|
||||
// show options
|
||||
for (int i = 0; i < _mi_option_last; i++) {
|
||||
mi_option_t option = (mi_option_t)i;
|
||||
mi_option_get(option);
|
||||
long l = mi_option_get(option); MI_UNUSED(l); // possibly initialize
|
||||
mi_option_desc_t* desc = &options[option];
|
||||
_mi_verbose_message("option '%s': %ld %s\n", desc->name, desc->value, (mi_option_has_size_in_kib(option) ? "KiB" : ""));
|
||||
}
|
||||
|
||||
// show build configuration
|
||||
_mi_verbose_message("debug level : %d\n", MI_DEBUG );
|
||||
_mi_verbose_message("secure level: %d\n", MI_SECURE );
|
||||
_mi_verbose_message("mem tracking: %s\n", MI_TRACK_TOOL);
|
||||
#if MI_GUARDED
|
||||
_mi_verbose_message("guarded build: %s\n", mi_option_get(mi_option_guarded_sample_rate) != 0 ? "enabled" : "disabled");
|
||||
#endif
|
||||
#if MI_TSAN
|
||||
_mi_verbose_message("thread santizer enabled\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
long _mi_option_get_fast(mi_option_t option) {
|
||||
|
|
179
src/stats.c
179
src/stats.c
|
@ -25,10 +25,7 @@ static void mi_stat_update_mt(mi_stat_count_t* stat, int64_t amount) {
|
|||
int64_t current = mi_atomic_addi64_relaxed(&stat->current, amount);
|
||||
mi_atomic_maxi64_relaxed(&stat->peak, current + amount);
|
||||
if (amount > 0) {
|
||||
mi_atomic_addi64_relaxed(&stat->allocated, amount);
|
||||
}
|
||||
else {
|
||||
mi_atomic_addi64_relaxed(&stat->freed, -amount);
|
||||
mi_atomic_addi64_relaxed(&stat->total, amount);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,44 +33,16 @@ static void mi_stat_update(mi_stat_count_t* stat, int64_t amount) {
|
|||
if (amount == 0) return;
|
||||
// add thread local
|
||||
stat->current += amount;
|
||||
if (stat->current > stat->peak) stat->peak = stat->current;
|
||||
if (amount > 0) {
|
||||
stat->allocated += amount;
|
||||
}
|
||||
else {
|
||||
stat->freed += -amount;
|
||||
}
|
||||
if (stat->current > stat->peak) { stat->peak = stat->current; }
|
||||
if (amount > 0) { stat->total += amount; }
|
||||
}
|
||||
|
||||
|
||||
// Adjust stats to compensate; for example before committing a range,
|
||||
// first adjust downwards with parts that were already committed so
|
||||
// we avoid double counting.
|
||||
static void mi_stat_adjust_mt(mi_stat_count_t* stat, int64_t amount, bool on_alloc) {
|
||||
if (amount == 0) return;
|
||||
// adjust atomically
|
||||
mi_atomic_addi64_relaxed(&stat->current, amount);
|
||||
mi_atomic_addi64_relaxed((on_alloc ? &stat->allocated : &stat->freed), amount);
|
||||
}
|
||||
|
||||
static void mi_stat_adjust(mi_stat_count_t* stat, int64_t amount, bool on_alloc) {
|
||||
if (amount == 0) return;
|
||||
stat->current += amount;
|
||||
if (on_alloc) {
|
||||
stat->allocated += amount;
|
||||
}
|
||||
else {
|
||||
stat->freed += amount;
|
||||
}
|
||||
}
|
||||
|
||||
void __mi_stat_counter_increase_mt(mi_stat_counter_t* stat, size_t amount) {
|
||||
mi_atomic_addi64_relaxed(&stat->count, 1);
|
||||
mi_atomic_addi64_relaxed(&stat->total, (int64_t)amount);
|
||||
}
|
||||
|
||||
void __mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount) {
|
||||
stat->count++;
|
||||
stat->total += amount;
|
||||
}
|
||||
|
||||
|
@ -91,77 +60,91 @@ void __mi_stat_decrease(mi_stat_count_t* stat, size_t amount) {
|
|||
mi_stat_update(stat, -((int64_t)amount));
|
||||
}
|
||||
|
||||
void __mi_stat_adjust_increase_mt(mi_stat_count_t* stat, size_t amount, bool on_alloc) {
|
||||
mi_stat_adjust_mt(stat, (int64_t)amount, on_alloc);
|
||||
}
|
||||
void __mi_stat_adjust_increase(mi_stat_count_t* stat, size_t amount, bool on_alloc) {
|
||||
mi_stat_adjust(stat, (int64_t)amount, on_alloc);
|
||||
|
||||
// Adjust stats to compensate; for example before committing a range,
|
||||
// first adjust downwards with parts that were already committed so
|
||||
// we avoid double counting.
|
||||
static void mi_stat_adjust_mt(mi_stat_count_t* stat, int64_t amount) {
|
||||
if (amount == 0) return;
|
||||
// adjust atomically
|
||||
mi_atomic_addi64_relaxed(&stat->current, amount);
|
||||
mi_atomic_addi64_relaxed(&stat->total, amount);
|
||||
}
|
||||
|
||||
void __mi_stat_adjust_decrease_mt(mi_stat_count_t* stat, size_t amount, bool on_alloc) {
|
||||
mi_stat_adjust_mt(stat, -((int64_t)amount), on_alloc);
|
||||
static void mi_stat_adjust(mi_stat_count_t* stat, int64_t amount) {
|
||||
if (amount == 0) return;
|
||||
stat->current += amount;
|
||||
stat->total += amount;
|
||||
}
|
||||
void __mi_stat_adjust_decrease(mi_stat_count_t* stat, size_t amount, bool on_alloc) {
|
||||
mi_stat_adjust(stat, -((int64_t)amount), on_alloc);
|
||||
|
||||
void __mi_stat_adjust_increase_mt(mi_stat_count_t* stat, size_t amount) {
|
||||
mi_stat_adjust_mt(stat, (int64_t)amount);
|
||||
}
|
||||
void __mi_stat_adjust_increase(mi_stat_count_t* stat, size_t amount) {
|
||||
mi_stat_adjust(stat, (int64_t)amount);
|
||||
}
|
||||
void __mi_stat_adjust_decrease_mt(mi_stat_count_t* stat, size_t amount) {
|
||||
mi_stat_adjust_mt(stat, -((int64_t)amount));
|
||||
}
|
||||
void __mi_stat_adjust_decrease(mi_stat_count_t* stat, size_t amount) {
|
||||
mi_stat_adjust(stat, -((int64_t)amount));
|
||||
}
|
||||
|
||||
|
||||
// must be thread safe as it is called from stats_merge
|
||||
static void mi_stat_add(mi_stat_count_t* stat, const mi_stat_count_t* src, int64_t unit) {
|
||||
static void mi_stat_add(mi_stat_count_t* stat, const mi_stat_count_t* src) {
|
||||
if (stat==src) return;
|
||||
if (src->allocated==0 && src->freed==0) return;
|
||||
mi_atomic_addi64_relaxed( &stat->allocated, src->allocated * unit);
|
||||
mi_atomic_addi64_relaxed( &stat->current, src->current * unit);
|
||||
mi_atomic_addi64_relaxed( &stat->freed, src->freed * unit);
|
||||
// peak scores do not work across threads..
|
||||
mi_atomic_addi64_relaxed( &stat->peak, src->peak * unit);
|
||||
if (src->total==0) return;
|
||||
mi_atomic_addi64_relaxed( &stat->total, src->total);
|
||||
mi_atomic_addi64_relaxed( &stat->current, src->current);
|
||||
// peak scores do really not work across threads ... we use conservative max
|
||||
mi_atomic_maxi64_relaxed( &stat->peak, src->peak); // or: mi_atomic_addi64_relaxed( &stat->peak, src->peak);
|
||||
}
|
||||
|
||||
static void mi_stat_counter_add(mi_stat_counter_t* stat, const mi_stat_counter_t* src, int64_t unit) {
|
||||
static void mi_stat_counter_add(mi_stat_counter_t* stat, const mi_stat_counter_t* src) {
|
||||
if (stat==src) return;
|
||||
mi_atomic_addi64_relaxed( &stat->total, src->total * unit);
|
||||
mi_atomic_addi64_relaxed( &stat->count, src->count * unit);
|
||||
mi_atomic_addi64_relaxed( &stat->total, src->total);
|
||||
}
|
||||
|
||||
// must be thread safe as it is called from stats_merge
|
||||
static void mi_stats_add(mi_stats_t* stats, const mi_stats_t* src) {
|
||||
if (stats==src) return;
|
||||
mi_stat_add(&stats->pages, &src->pages,1);
|
||||
mi_stat_add(&stats->reserved, &src->reserved, 1);
|
||||
mi_stat_add(&stats->committed, &src->committed, 1);
|
||||
mi_stat_add(&stats->reset, &src->reset, 1);
|
||||
mi_stat_add(&stats->purged, &src->purged, 1);
|
||||
mi_stat_add(&stats->page_committed, &src->page_committed, 1);
|
||||
mi_stat_add(&stats->pages, &src->pages);
|
||||
mi_stat_add(&stats->reserved, &src->reserved);
|
||||
mi_stat_add(&stats->committed, &src->committed);
|
||||
mi_stat_add(&stats->reset, &src->reset);
|
||||
mi_stat_add(&stats->purged, &src->purged);
|
||||
mi_stat_add(&stats->page_committed, &src->page_committed);
|
||||
|
||||
mi_stat_add(&stats->pages_abandoned, &src->pages_abandoned, 1);
|
||||
mi_stat_add(&stats->threads, &src->threads, 1);
|
||||
mi_stat_add(&stats->pages_abandoned, &src->pages_abandoned);
|
||||
mi_stat_add(&stats->threads, &src->threads);
|
||||
|
||||
mi_stat_add(&stats->malloc, &src->malloc, 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);
|
||||
mi_stat_add(&stats->malloc, &src->malloc);
|
||||
mi_stat_add(&stats->normal, &src->normal);
|
||||
mi_stat_add(&stats->huge, &src->huge);
|
||||
mi_stat_add(&stats->giant, &src->giant);
|
||||
|
||||
mi_stat_counter_add(&stats->pages_extended, &src->pages_extended, 1);
|
||||
mi_stat_counter_add(&stats->mmap_calls, &src->mmap_calls, 1);
|
||||
mi_stat_counter_add(&stats->commit_calls, &src->commit_calls, 1);
|
||||
mi_stat_counter_add(&stats->reset_calls, &src->reset_calls, 1);
|
||||
mi_stat_counter_add(&stats->purge_calls, &src->purge_calls, 1);
|
||||
mi_stat_counter_add(&stats->pages_extended, &src->pages_extended);
|
||||
mi_stat_counter_add(&stats->mmap_calls, &src->mmap_calls);
|
||||
mi_stat_counter_add(&stats->commit_calls, &src->commit_calls);
|
||||
mi_stat_counter_add(&stats->reset_calls, &src->reset_calls);
|
||||
mi_stat_counter_add(&stats->purge_calls, &src->purge_calls);
|
||||
|
||||
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->guarded_alloc_count, &src->guarded_alloc_count, 1);
|
||||
mi_stat_counter_add(&stats->page_no_retire, &src->page_no_retire);
|
||||
mi_stat_counter_add(&stats->searches, &src->searches);
|
||||
mi_stat_counter_add(&stats->normal_count, &src->normal_count);
|
||||
mi_stat_counter_add(&stats->huge_count, &src->huge_count);
|
||||
mi_stat_counter_add(&stats->guarded_alloc_count, &src->guarded_alloc_count);
|
||||
|
||||
mi_stat_counter_add(&stats->pages_extended, &src->pages_extended, 1);
|
||||
mi_stat_counter_add(&stats->pages_reclaim_on_alloc, &src->pages_reclaim_on_alloc, 1);
|
||||
mi_stat_counter_add(&stats->pages_reclaim_on_free, &src->pages_reclaim_on_free, 1);
|
||||
mi_stat_counter_add(&stats->pages_reabandon_full, &src->pages_reabandon_full, 1);
|
||||
mi_stat_counter_add(&stats->pages_unabandon_busy_wait, &src->pages_unabandon_busy_wait, 1);
|
||||
mi_stat_counter_add(&stats->pages_extended, &src->pages_extended);
|
||||
mi_stat_counter_add(&stats->pages_reclaim_on_alloc, &src->pages_reclaim_on_alloc);
|
||||
mi_stat_counter_add(&stats->pages_reclaim_on_free, &src->pages_reclaim_on_free);
|
||||
mi_stat_counter_add(&stats->pages_reabandon_full, &src->pages_reabandon_full);
|
||||
mi_stat_counter_add(&stats->pages_unabandon_busy_wait, &src->pages_unabandon_busy_wait);
|
||||
#if MI_STAT>1
|
||||
for (size_t i = 0; i <= MI_BIN_HUGE; i++) {
|
||||
if (src->normal_bins[i].allocated > 0 || src->normal_bins[i].freed > 0) {
|
||||
mi_stat_add(&stats->normal_bins[i], &src->normal_bins[i], 1);
|
||||
if (src->normal_bins[i].total > 0) {
|
||||
mi_stat_add(&stats->normal_bins[i], &src->normal_bins[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -217,26 +200,26 @@ static void mi_stat_print_ex(const mi_stat_count_t* stat, const char* msg, int64
|
|||
if (unit != 0) {
|
||||
if (unit > 0) {
|
||||
mi_print_amount(stat->peak, unit, out, arg);
|
||||
mi_print_amount(stat->allocated, unit, out, arg);
|
||||
mi_print_amount(stat->freed, unit, out, arg);
|
||||
mi_print_amount(stat->total, unit, out, arg);
|
||||
// mi_print_amount(stat->freed, unit, out, arg);
|
||||
mi_print_amount(stat->current, unit, out, arg);
|
||||
mi_print_amount(unit, 1, out, arg);
|
||||
mi_print_count(stat->allocated, unit, out, arg);
|
||||
mi_print_count(stat->total, unit, out, arg);
|
||||
}
|
||||
else {
|
||||
mi_print_amount(stat->peak, -1, out, arg);
|
||||
mi_print_amount(stat->allocated, -1, out, arg);
|
||||
mi_print_amount(stat->freed, -1, out, arg);
|
||||
mi_print_amount(stat->total, -1, out, arg);
|
||||
// mi_print_amount(stat->freed, -1, out, arg);
|
||||
mi_print_amount(stat->current, -1, out, arg);
|
||||
if (unit == -1) {
|
||||
_mi_fprintf(out, arg, "%24s", "");
|
||||
}
|
||||
else {
|
||||
mi_print_amount(-unit, 1, out, arg);
|
||||
mi_print_count((stat->allocated / -unit), 0, out, arg);
|
||||
mi_print_count((stat->total / -unit), 0, out, arg);
|
||||
}
|
||||
}
|
||||
if (stat->allocated > stat->freed) {
|
||||
if (stat->current != 0) {
|
||||
_mi_fprintf(out, arg, " ");
|
||||
_mi_fprintf(out, arg, (notok == NULL ? "not all freed" : notok));
|
||||
_mi_fprintf(out, arg, "\n");
|
||||
|
@ -247,7 +230,7 @@ static void mi_stat_print_ex(const mi_stat_count_t* stat, const char* msg, int64
|
|||
}
|
||||
else {
|
||||
mi_print_amount(stat->peak, 1, out, arg);
|
||||
mi_print_amount(stat->allocated, 1, out, arg);
|
||||
mi_print_amount(stat->total, 1, out, arg);
|
||||
_mi_fprintf(out, arg, "%11s", " "); // no freed
|
||||
mi_print_amount(stat->current, 1, out, arg);
|
||||
_mi_fprintf(out, arg, "\n");
|
||||
|
@ -272,7 +255,7 @@ static void mi_stat_counter_print(const mi_stat_counter_t* stat, const char* msg
|
|||
|
||||
|
||||
static void mi_stat_counter_print_avg(const mi_stat_counter_t* stat, const char* msg, mi_output_fun* out, void* arg) {
|
||||
const int64_t avg_tens = (stat->count == 0 ? 0 : (stat->total*10 / stat->count));
|
||||
const int64_t avg_tens = (stat->total == 0 ? 0 : (stat->total*10 / stat->total));
|
||||
const long avg_whole = (long)(avg_tens/10);
|
||||
const long avg_frac1 = (long)(avg_tens%10);
|
||||
_mi_fprintf(out, arg, "%10s: %5ld.%ld avg\n", msg, avg_whole, avg_frac1);
|
||||
|
@ -280,7 +263,7 @@ static void mi_stat_counter_print_avg(const mi_stat_counter_t* stat, const char*
|
|||
|
||||
|
||||
static void mi_print_header(mi_output_fun* out, void* arg ) {
|
||||
_mi_fprintf(out, arg, "%10s: %11s %11s %11s %11s %11s %11s\n", "heap stats", "peak ", "total ", "freed ", "current ", "unit ", "count ");
|
||||
_mi_fprintf(out, arg, "%10s: %11s %11s %11s %11s %11s\n", "heap stats", "peak ", "total ", "current ", "unit ", "total# ");
|
||||
}
|
||||
|
||||
#if MI_STAT>1
|
||||
|
@ -288,7 +271,7 @@ static void mi_stats_print_bins(const mi_stat_count_t* bins, size_t max, const c
|
|||
bool found = false;
|
||||
char buf[64];
|
||||
for (size_t i = 0; i <= max; i++) {
|
||||
if (bins[i].allocated > 0) {
|
||||
if (bins[i].total > 0) {
|
||||
found = true;
|
||||
int64_t unit = _mi_bin_size((uint8_t)i);
|
||||
_mi_snprintf(buf, 64, "%s %3lu", fmt, (long)i);
|
||||
|
@ -352,11 +335,11 @@ static void _mi_stats_print(mi_stats_t* stats, mi_output_fun* out0, void* arg0)
|
|||
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_count_t total = { 0,0,0,0 };
|
||||
mi_stat_add(&total, &stats->normal, 1);
|
||||
mi_stat_add(&total, &stats->huge, 1);
|
||||
mi_stat_print(&stats->normal, "normal", (stats->normal_count.total == 0 ? 1 : -1), out, arg);
|
||||
mi_stat_print(&stats->huge, "huge", (stats->huge_count.total == 0 ? 1 : -1), out, arg);
|
||||
mi_stat_count_t total = { 0,0,0 };
|
||||
mi_stat_add(&total, &stats->normal);
|
||||
mi_stat_add(&total, &stats->huge);
|
||||
mi_stat_print(&total, "total", 1, out, arg);
|
||||
#endif
|
||||
#if MI_STAT>1
|
||||
|
|
Loading…
Add table
Reference in a new issue