use mi_os_zalloc for submaps

This commit is contained in:
Daan 2025-06-06 21:04:24 -07:00
commit eeab42be46
3 changed files with 35 additions and 21 deletions

View file

@ -59,7 +59,7 @@ int _mi_prim_commit(void* addr, size_t size, bool* is_zero);
// pre: needs_recommit != NULL // pre: needs_recommit != NULL
int _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit); int _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit);
// Reset memory. The range keeps being accessible but the content might be reset. // Reset memory. The range keeps being accessible but the content might be reset to zero at any moment.
// Returns error code or 0 on success. // Returns error code or 0 on success.
int _mi_prim_reset(void* addr, size_t size); int _mi_prim_reset(void* addr, size_t size);

View file

@ -188,6 +188,7 @@ void _mi_os_free_ex(void* addr, size_t size, bool still_committed, mi_memid_t me
if (mi_memkind_is_os(memid.memkind)) { if (mi_memkind_is_os(memid.memkind)) {
size_t csize = memid.mem.os.size; size_t csize = memid.mem.os.size;
if (csize==0) { csize = _mi_os_good_alloc_size(size); } if (csize==0) { csize = _mi_os_good_alloc_size(size); }
mi_assert_internal(csize >= size);
size_t commit_size = (still_committed ? csize : 0); size_t commit_size = (still_committed ? csize : 0);
void* base = addr; void* base = addr;
// different base? (due to alignment) // different base? (due to alignment)
@ -351,9 +352,11 @@ void* _mi_os_alloc(size_t size, mi_memid_t* memid) {
bool os_is_large = false; bool os_is_large = false;
bool os_is_zero = false; bool os_is_zero = false;
void* p = mi_os_prim_alloc(size, 0, true, false, &os_is_large, &os_is_zero); void* p = mi_os_prim_alloc(size, 0, true, false, &os_is_large, &os_is_zero);
if (p != NULL) { if (p == NULL) return NULL;
*memid = _mi_memid_create_os(p, size, true, os_is_zero, os_is_large); *memid = _mi_memid_create_os(p, size, true, os_is_zero, os_is_large);
} mi_assert_internal(memid->mem.os.size >= size);
mi_assert_internal(memid->initially_committed);
return p; return p;
} }
@ -369,24 +372,38 @@ void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allo
bool os_is_zero = false; bool os_is_zero = false;
void* os_base = NULL; void* os_base = NULL;
void* p = mi_os_prim_alloc_aligned(size, alignment, commit, allow_large, &os_is_large, &os_is_zero, &os_base ); void* p = mi_os_prim_alloc_aligned(size, alignment, commit, allow_large, &os_is_large, &os_is_zero, &os_base );
if (p != NULL) { if (p == NULL) return NULL;
*memid = _mi_memid_create_os(p, size, commit, os_is_zero, os_is_large); *memid = _mi_memid_create_os(p, size, commit, os_is_zero, os_is_large);
memid->mem.os.base = os_base; memid->mem.os.base = os_base;
memid->mem.os.size += ((uint8_t*)p - (uint8_t*)os_base); // todo: return from prim_alloc_aligned? memid->mem.os.size += ((uint8_t*)p - (uint8_t*)os_base); // todo: return from prim_alloc_aligned?
mi_assert_internal(memid->mem.os.size >= size);
mi_assert_internal(_mi_is_aligned(p,alignment));
mi_assert_internal(!commit || memid->initially_committed);
mi_assert_internal(!memid->initially_zero || memid->initially_committed);
return p;
} }
mi_decl_nodiscard static void* mi_os_ensure_zero(void* p, size_t size, mi_memid_t* memid) {
if (p==NULL || size==0 || memid->initially_zero) return p;
if (!memid->initially_committed) {
bool is_zero = false;
if (!_mi_os_commit(p, size, &is_zero)) {
_mi_os_free(p, size, *memid);
return NULL;
}
memid->initially_committed = true;
}
_mi_memzero_aligned(p,size);
memid->initially_zero = true;
return p; return p;
} }
void* _mi_os_zalloc(size_t size, mi_memid_t* memid) { void* _mi_os_zalloc(size_t size, mi_memid_t* memid) {
void* p = _mi_os_alloc(size,memid); void* p = _mi_os_alloc(size,memid);
if (p == NULL) return NULL; return mi_os_ensure_zero(p, size, memid);
// zero the OS memory if needed
if (!memid->initially_zero) {
_mi_memzero_aligned(p, size);
memid->initially_zero = true;
}
return p;
} }
/* ----------------------------------------------------------- /* -----------------------------------------------------------

View file

@ -297,14 +297,11 @@ static mi_page_t** mi_page_map_ensure_submap_at(size_t idx) {
mi_memid_t memid; mi_memid_t memid;
mi_page_t** expect = sub; mi_page_t** expect = sub;
const size_t submap_size = MI_PAGE_MAP_SUB_SIZE; const size_t submap_size = MI_PAGE_MAP_SUB_SIZE;
sub = (mi_page_t**)_mi_os_alloc(submap_size, &memid); sub = (mi_page_t**)_mi_os_zalloc(submap_size, &memid);
if (sub == NULL) { if (sub == NULL) {
_mi_error_message(EFAULT, "internal error: unable to extend the page map\n"); _mi_error_message(EFAULT, "internal error: unable to extend the page map\n");
return NULL; return NULL;
} }
if (!memid.initially_zero) {
_mi_memzero_aligned(sub, submap_size);
}
if (!mi_atomic_cas_ptr_strong_acq_rel(mi_page_t*, &_mi_page_map[idx], &expect, sub)) { if (!mi_atomic_cas_ptr_strong_acq_rel(mi_page_t*, &_mi_page_map[idx], &expect, sub)) {
// another thread already allocated it.. free and continue // another thread already allocated it.. free and continue
_mi_os_free(sub, submap_size, memid); _mi_os_free(sub, submap_size, memid);