Skip to content

Commit 5445cdb

Browse files
committed
Exposing status for thread local heaps. Adding dedicated method for os memory subsystem stats.
1 parent 26b792d commit 5445cdb

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ option(MI_NO_PADDING "Force no use of padding even in DEBUG mode etc." OF
3434
option(MI_INSTALL_TOPLEVEL "Install directly into $CMAKE_INSTALL_PREFIX instead of PREFIX/lib/mimalloc-version" OFF)
3535
option(MI_NO_THP "Disable transparent huge pages support on Linux/Android for the mimalloc process only" OFF)
3636
option(MI_EXTRA_CPPDEFS "Extra pre-processor definitions (use as `-DMI_EXTRA_CPPDEFS=\"opt1=val1;opt2=val2\"`)" "")
37+
option(MI_STAT_LEVEL "Optionally override stats level to 1 or 2 when debug not enable" 0)
3738

3839
# negated options for vcpkg features
3940
option(MI_NO_USE_CXX "Use plain C compilation (has priority over MI_USE_CXX)" OFF)
@@ -78,6 +79,10 @@ else()
7879
set(mi_defines "")
7980
endif()
8081

82+
if (MI_STAT_LEVEL GREATER 0)
83+
add_compile_definitions(MI_STAT=${MI_STAT_LEVEL})
84+
endif ()
85+
8186
# pass git revision as a define
8287
if(EXISTS "${CMAKE_SOURCE_DIR}/.git/index")
8388
find_package(Git)

include/mimalloc-stats.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,33 @@ typedef struct mi_stats_s
8888
#undef MI_STAT_COUNT
8989
#undef MI_STAT_COUNTER
9090

91+
typedef struct mi_os_stats_s {
92+
mi_stat_count_t reserved;
93+
mi_stat_count_t committed;
94+
mi_stat_count_t reset;
95+
mi_stat_count_t purged;
96+
mi_stat_counter_t mmap_calls;
97+
mi_stat_counter_t commit_calls;
98+
mi_stat_counter_t reset_calls;
99+
mi_stat_counter_t purge_calls;
100+
} mi_os_stats_t;
101+
91102
// Exported definitions
92103
#ifdef __cplusplus
93104
extern "C" {
94105
#endif
95106

96107
mi_decl_export void mi_stats_get( size_t stats_size, mi_stats_t* stats ) mi_attr_noexcept;
97108
mi_decl_export char* mi_stats_get_json( size_t buf_size, char* buf ) mi_attr_noexcept; // use mi_free to free the result if the input buf == NULL
109+
110+
// returns the thread local stats for the current thread local heap. Memory returned is non-owned.
111+
mi_decl_export const mi_stats_t* mi_thread_stats(void) mi_attr_noexcept;
112+
113+
// returns the thread local stats for the given heap. Memory returned is non-owned.
114+
mi_decl_export const mi_stats_t* mi_thread_heap_stats(const mi_heap_t* heap) mi_attr_noexcept;
115+
116+
// returns stats related to os memory subsystem.
117+
mi_decl_export mi_os_stats_t mi_os_stats(void) mi_attr_noexcept;
98118

99119
#ifdef __cplusplus
100120
}

src/stats.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,22 @@ static void mi_stats_add(mi_stats_t* stats, const mi_stats_t* src) {
118118
}
119119
}
120120

121+
static void mi_stat_atomic_copy(mi_stat_count_t* dst, const mi_stat_count_t* src) {
122+
if (dst==src) return;
123+
if (src->total==0) return;
124+
125+
dst->total = (mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)(&src->total)));
126+
dst->current = (mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)(&src->current)));
127+
dst->peak = (mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)(&src->peak)));
128+
}
129+
130+
static void mi_stat_counter_atomic_copy(mi_stat_counter_t* dst, const mi_stat_counter_t* src) {
131+
if (dst==src) return;
132+
if (src->total==0) return;
133+
134+
dst->total = (mi_atomic_loadi64_relaxed((_Atomic(int64_t)*)(&src->total)));
135+
}
136+
121137
#undef MI_STAT_COUNT
122138
#undef MI_STAT_COUNTER
123139

@@ -411,6 +427,30 @@ void mi_thread_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept {
411427
_mi_stats_print(mi_stats_get_default(), out, arg);
412428
}
413429

430+
const mi_stats_t* mi_thread_heap_stats(const mi_heap_t* heap) mi_attr_noexcept {
431+
return &heap->tld->stats;
432+
}
433+
434+
const mi_stats_t* mi_thread_stats(void) mi_attr_noexcept {
435+
return mi_thread_heap_stats(mi_heap_get_default());
436+
}
437+
438+
mi_os_stats_t mi_os_stats(void) mi_attr_noexcept {
439+
mi_os_stats_t stats;
440+
memset(&stats, 0, sizeof(mi_os_stats_t));
441+
442+
mi_stat_atomic_copy(&stats.reserved, &_mi_stats_main.reserved);
443+
mi_stat_atomic_copy(&stats.committed, &_mi_stats_main.committed);
444+
mi_stat_atomic_copy(&stats.reset, &_mi_stats_main.reset);
445+
mi_stat_atomic_copy(&stats.purged, &_mi_stats_main.purged);
446+
447+
mi_stat_counter_atomic_copy(&stats.mmap_calls, &_mi_stats_main.mmap_calls);
448+
mi_stat_counter_atomic_copy(&stats.commit_calls, &_mi_stats_main.commit_calls);
449+
mi_stat_counter_atomic_copy(&stats.reset_calls, &_mi_stats_main.reset_calls);
450+
mi_stat_counter_atomic_copy(&stats.purge_calls, &_mi_stats_main.purge_calls);
451+
452+
return stats;
453+
}
414454

415455
// ----------------------------------------------------------------
416456
// Basic timer for convenience; use milli-seconds to avoid doubles

0 commit comments

Comments
 (0)