Merge branch 'dev' of e:\dev\mimalloc3 into dev

This commit is contained in:
Daan Leijen 2025-01-05 15:43:15 -08:00
commit 83fd6e33fb
6 changed files with 29 additions and 20 deletions

View file

@ -276,7 +276,7 @@ mi_decl_export int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size
mi_decl_export int mi_reserve_os_memory(size_t size, bool commit, bool allow_large) mi_attr_noexcept; mi_decl_export int mi_reserve_os_memory(size_t size, bool commit, bool allow_large) mi_attr_noexcept;
mi_decl_export bool mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node) mi_attr_noexcept; mi_decl_export bool mi_manage_os_memory(void* start, size_t size, bool is_committed, bool is_large, bool is_zero, int numa_node) mi_attr_noexcept;
mi_decl_export void mi_debug_show_arenas(bool show_inuse) mi_attr_noexcept; mi_decl_export void mi_debug_show_arenas(void) mi_attr_noexcept;
// Experimental: heaps associated with specific memory arena's // Experimental: heaps associated with specific memory arena's
typedef int mi_arena_id_t; typedef int mi_arena_id_t;

View file

@ -64,8 +64,8 @@ terms of the MIT license. A copy of the license can be found in the file
// "libc.c" // "libc.c"
#include <stdarg.h> #include <stdarg.h>
void _mi_vsnprintf(char* buf, size_t bufsize, const char* fmt, va_list args); int _mi_vsnprintf(char* buf, size_t bufsize, const char* fmt, va_list args);
void _mi_snprintf(char* buf, size_t buflen, const char* fmt, ...); int _mi_snprintf(char* buf, size_t buflen, const char* fmt, ...);
char _mi_toupper(char c); char _mi_toupper(char c);
int _mi_strnicmp(const char* s, const char* t, size_t n); int _mi_strnicmp(const char* s, const char* t, size_t n);
void _mi_strlcpy(char* dest, const char* src, size_t dest_size); void _mi_strlcpy(char* dest, const char* src, size_t dest_size);

View file

@ -923,7 +923,8 @@ static size_t mi_debug_show_bitmap(const char* prefix, const char* header, size_
return inuse_count; return inuse_count;
} }
void mi_debug_show_arenas(bool show_inuse) mi_attr_noexcept { void mi_debug_show_arenas(void) mi_attr_noexcept {
const bool show_inuse = true;
size_t max_arenas = mi_atomic_load_relaxed(&mi_arena_count); size_t max_arenas = mi_atomic_load_relaxed(&mi_arena_count);
size_t inuse_total = 0; size_t inuse_total = 0;
//size_t abandoned_total = 0; //size_t abandoned_total = 0;

View file

@ -7,7 +7,7 @@ terms of the MIT license. A copy of the license can be found in the file
// -------------------------------------------------------- // --------------------------------------------------------
// This module defines various std libc functions to reduce // This module defines various std libc functions to reduce
// the dependency on libc, and also prevent errors caused // the dependency on libc, and also prevent errors caused
// by some libc implementations when called before `main` // by some libc implementations when called before `main`
// executes (due to malloc redirection) // executes (due to malloc redirection)
// -------------------------------------------------------- // --------------------------------------------------------
@ -83,7 +83,7 @@ bool _mi_getenv(const char* name, char* result, size_t result_size) {
// Define our own limited `_mi_vsnprintf` and `_mi_snprintf` // Define our own limited `_mi_vsnprintf` and `_mi_snprintf`
// This is mostly to avoid calling these when libc is not yet // This is mostly to avoid calling these when libc is not yet
// initialized (and to reduce dependencies) // initialized (and to reduce dependencies)
// //
// format: d i, p x u, s // format: d i, p x u, s
// prec: z l ll L // prec: z l ll L
// width: 10 // width: 10
@ -130,7 +130,7 @@ static void mi_out_alignright(char fill, char* start, size_t len, size_t extra,
} }
static void mi_out_num(uintmax_t x, size_t base, char prefix, char** out, char* end) static void mi_out_num(uintmax_t x, size_t base, char prefix, char** out, char* end)
{ {
if (x == 0 || base == 0 || base > 16) { if (x == 0 || base == 0 || base > 16) {
if (prefix != 0) { mi_outc(prefix, out, end); } if (prefix != 0) { mi_outc(prefix, out, end); }
@ -144,8 +144,8 @@ static void mi_out_num(uintmax_t x, size_t base, char prefix, char** out, char*
mi_outc((digit <= 9 ? '0' + digit : 'A' + digit - 10),out,end); mi_outc((digit <= 9 ? '0' + digit : 'A' + digit - 10),out,end);
x = x / base; x = x / base;
} }
if (prefix != 0) { if (prefix != 0) {
mi_outc(prefix, out, end); mi_outc(prefix, out, end);
} }
size_t len = *out - start; size_t len = *out - start;
// and reverse in-place // and reverse in-place
@ -160,8 +160,8 @@ static void mi_out_num(uintmax_t x, size_t base, char prefix, char** out, char*
#define MI_NEXTC() c = *in; if (c==0) break; in++; #define MI_NEXTC() c = *in; if (c==0) break; in++;
void _mi_vsnprintf(char* buf, size_t bufsize, const char* fmt, va_list args) { int _mi_vsnprintf(char* buf, size_t bufsize, const char* fmt, va_list args) {
if (buf == NULL || bufsize == 0 || fmt == NULL) return; if (buf == NULL || bufsize == 0 || fmt == NULL) return 0;
buf[bufsize - 1] = 0; buf[bufsize - 1] = 0;
char* const end = buf + (bufsize - 1); char* const end = buf + (bufsize - 1);
const char* in = fmt; const char* in = fmt;
@ -181,7 +181,7 @@ void _mi_vsnprintf(char* buf, size_t bufsize, const char* fmt, va_list args) {
size_t width = 0; size_t width = 0;
char numtype = 'd'; char numtype = 'd';
char numplus = 0; char numplus = 0;
bool alignright = true; bool alignright = true;
if (c == '+' || c == ' ') { numplus = c; MI_NEXTC(); } if (c == '+' || c == ' ') { numplus = c; MI_NEXTC(); }
if (c == '-') { alignright = false; MI_NEXTC(); } if (c == '-') { alignright = false; MI_NEXTC(); }
if (c == '0') { fill = '0'; MI_NEXTC(); } if (c == '0') { fill = '0'; MI_NEXTC(); }
@ -191,7 +191,7 @@ void _mi_vsnprintf(char* buf, size_t bufsize, const char* fmt, va_list args) {
width = (10 * width) + (c - '0'); MI_NEXTC(); width = (10 * width) + (c - '0'); MI_NEXTC();
} }
if (c == 0) break; // extra check due to while if (c == 0) break; // extra check due to while
} }
if (c == 'z' || c == 't' || c == 'L') { numtype = c; MI_NEXTC(); } if (c == 'z' || c == 't' || c == 'L') { numtype = c; MI_NEXTC(); }
else if (c == 'l') { else if (c == 'l') {
numtype = c; MI_NEXTC(); numtype = c; MI_NEXTC();
@ -265,11 +265,13 @@ void _mi_vsnprintf(char* buf, size_t bufsize, const char* fmt, va_list args) {
} }
mi_assert_internal(out <= end); mi_assert_internal(out <= end);
*out = 0; *out = 0;
return (int)(out - buf);
} }
void _mi_snprintf(char* buf, size_t buflen, const char* fmt, ...) { int _mi_snprintf(char* buf, size_t buflen, const char* fmt, ...) {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
_mi_vsnprintf(buf, buflen, fmt, args); const int written = _mi_vsnprintf(buf, buflen, fmt, args);
va_end(args); va_end(args);
return written;
} }

View file

@ -411,7 +411,7 @@ void _mi_page_force_abandon(mi_page_t* page) {
// ensure this page is no longer in the heap delayed free list // ensure this page is no longer in the heap delayed free list
_mi_heap_delayed_free_all(heap); _mi_heap_delayed_free_all(heap);
// We can still access the page meta-info even if it is freed as we ensure // We can still access the page meta-info even if it is freed as we ensure
// in `mi_segment_force_abandon` that the segment is not freed (yet) // in `mi_segment_force_abandon` that the segment is not freed (yet)
if (page->capacity == 0) return; // it may have been freed now if (page->capacity == 0) return; // it may have been freed now
@ -990,14 +990,20 @@ void* _mi_malloc_generic(mi_heap_t* heap, size_t size, bool zero, size_t huge_al
mi_assert_internal(mi_page_block_size(page) >= size); mi_assert_internal(mi_page_block_size(page) >= size);
// and try again, this time succeeding! (i.e. this should never recurse through _mi_page_malloc) // and try again, this time succeeding! (i.e. this should never recurse through _mi_page_malloc)
void* p;
if mi_unlikely(zero && mi_page_is_huge(page)) { if mi_unlikely(zero && mi_page_is_huge(page)) {
// note: we cannot call _mi_page_malloc with zeroing for huge blocks; we zero it afterwards in that case. // note: we cannot call _mi_page_malloc with zeroing for huge blocks; we zero it afterwards in that case.
void* p = _mi_page_malloc(heap, page, size); p = _mi_page_malloc(heap, page, size);
mi_assert_internal(p != NULL); mi_assert_internal(p != NULL);
_mi_memzero_aligned(p, mi_page_usable_block_size(page)); _mi_memzero_aligned(p, mi_page_usable_block_size(page));
return p;
} }
else { else {
return _mi_page_malloc_zero(heap, page, size, zero); p = _mi_page_malloc_zero(heap, page, size, zero);
mi_assert_internal(p != NULL);
} }
// move singleton pages to the full queue
if (page->reserved == page->used) {
mi_page_to_full(page, mi_page_queue_of(page));
}
return p;
} }

View file

@ -316,7 +316,7 @@ int main(int argc, char** argv) {
#ifndef USE_STD_MALLOC #ifndef USE_STD_MALLOC
#ifndef NDEBUG #ifndef NDEBUG
mi_debug_show_arenas(true); mi_debug_show_arenas();
mi_collect(true); mi_collect(true);
#endif #endif
#endif #endif