Skip to content

Commit 2f0540c

Browse files
committed
add _mi_os_zalloc
1 parent d743140 commit 2f0540c

File tree

6 files changed

+50
-33
lines changed

6 files changed

+50
-33
lines changed

include/mimalloc/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ void _mi_heap_guarded_init(mi_heap_t* heap);
154154
// os.c
155155
void _mi_os_init(void); // called from process init
156156
void* _mi_os_alloc(size_t size, mi_memid_t* memid);
157+
void* _mi_os_zalloc(size_t size, mi_memid_t* memid);
157158
void _mi_os_free(void* p, size_t size, mi_memid_t memid);
158159
void _mi_os_free_ex(void* p, size_t size, bool still_committed, mi_memid_t memid);
159160

include/mimalloc/prim.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ int _mi_prim_commit(void* addr, size_t size, bool* is_zero);
5959
// pre: needs_recommit != NULL
6060
int _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit);
6161

62-
// Reset memory. The range keeps being accessible but the content might be reset.
62+
// Reset memory. The range keeps being accessible but the content might be reset to zero at any moment.
6363
// Returns error code or 0 on success.
6464
int _mi_prim_reset(void* addr, size_t size);
6565

src/arena.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -188,14 +188,9 @@ void* _mi_arena_meta_zalloc(size_t size, mi_memid_t* memid) {
188188
if (p != NULL) return p;
189189

190190
// or fall back to the OS
191-
p = _mi_os_alloc(size, memid);
191+
p = _mi_os_zalloc(size, memid);
192192
if (p == NULL) return NULL;
193193

194-
// zero the OS memory if needed
195-
if (!memid->initially_zero) {
196-
_mi_memzero_aligned(p, size);
197-
memid->initially_zero = true;
198-
}
199194
return p;
200195
}
201196

src/init.c

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -298,40 +298,32 @@ static _Atomic(mi_thread_data_t*) td_cache[TD_CACHE_SIZE];
298298

299299
static mi_thread_data_t* mi_thread_data_zalloc(void) {
300300
// try to find thread metadata in the cache
301-
bool is_zero = false;
302301
mi_thread_data_t* td = NULL;
303302
for (int i = 0; i < TD_CACHE_SIZE; i++) {
304303
td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]);
305304
if (td != NULL) {
306305
// found cached allocation, try use it
307306
td = mi_atomic_exchange_ptr_acq_rel(mi_thread_data_t, &td_cache[i], NULL);
308307
if (td != NULL) {
309-
break;
308+
_mi_memzero(td, offsetof(mi_thread_data_t,memid));
309+
return td;
310310
}
311311
}
312312
}
313313

314314
// if that fails, allocate as meta data
315+
mi_memid_t memid;
316+
td = (mi_thread_data_t*)_mi_os_zalloc(sizeof(mi_thread_data_t), &memid);
315317
if (td == NULL) {
316-
mi_memid_t memid;
317-
td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &memid);
318+
// if this fails, try once more. (issue #257)
319+
td = (mi_thread_data_t*)_mi_os_zalloc(sizeof(mi_thread_data_t), &memid);
318320
if (td == NULL) {
319-
// if this fails, try once more. (issue #257)
320-
td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &memid);
321-
if (td == NULL) {
322-
// really out of memory
323-
_mi_error_message(ENOMEM, "unable to allocate thread local heap metadata (%zu bytes)\n", sizeof(mi_thread_data_t));
324-
}
325-
}
326-
if (td != NULL) {
327-
td->memid = memid;
328-
is_zero = memid.initially_zero;
321+
// really out of memory
322+
_mi_error_message(ENOMEM, "unable to allocate thread local heap metadata (%zu bytes)\n", sizeof(mi_thread_data_t));
323+
return NULL;
329324
}
330325
}
331-
332-
if (td != NULL && !is_zero) {
333-
_mi_memzero_aligned(td, offsetof(mi_thread_data_t,memid));
334-
}
326+
td->memid = memid;
335327
return td;
336328
}
337329

src/os.c

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ void _mi_os_free_ex(void* addr, size_t size, bool still_committed, mi_memid_t me
182182
if (mi_memkind_is_os(memid.memkind)) {
183183
size_t csize = memid.mem.os.size;
184184
if (csize==0) { csize = _mi_os_good_alloc_size(size); }
185+
mi_assert_internal(csize >= size);
185186
size_t commit_size = (still_committed ? csize : 0);
186187
void* base = addr;
187188
// different base? (due to alignment)
@@ -341,9 +342,11 @@ void* _mi_os_alloc(size_t size, mi_memid_t* memid) {
341342
bool os_is_large = false;
342343
bool os_is_zero = false;
343344
void* p = mi_os_prim_alloc(size, 0, true, false, &os_is_large, &os_is_zero);
344-
if (p != NULL) {
345-
*memid = _mi_memid_create_os(p, size, true, os_is_zero, os_is_large);
346-
}
345+
if (p == NULL) return NULL;
346+
347+
*memid = _mi_memid_create_os(p, size, true, os_is_zero, os_is_large);
348+
mi_assert_internal(memid->mem.os.size >= size);
349+
mi_assert_internal(memid->initially_committed);
347350
return p;
348351
}
349352

@@ -359,14 +362,40 @@ void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allo
359362
bool os_is_zero = false;
360363
void* os_base = NULL;
361364
void* p = mi_os_prim_alloc_aligned(size, alignment, commit, allow_large, &os_is_large, &os_is_zero, &os_base );
362-
if (p != NULL) {
363-
*memid = _mi_memid_create_os(p, size, commit, os_is_zero, os_is_large);
364-
memid->mem.os.base = os_base;
365-
memid->mem.os.size += ((uint8_t*)p - (uint8_t*)os_base); // todo: return from prim_alloc_aligned?
365+
if (p == NULL) return NULL;
366+
367+
*memid = _mi_memid_create_os(p, size, commit, os_is_zero, os_is_large);
368+
memid->mem.os.base = os_base;
369+
memid->mem.os.size += ((uint8_t*)p - (uint8_t*)os_base); // todo: return from prim_alloc_aligned?
370+
371+
mi_assert_internal(memid->mem.os.size >= size);
372+
mi_assert_internal(_mi_is_aligned(p,alignment));
373+
mi_assert_internal(!commit || memid->initially_committed);
374+
mi_assert_internal(!memid->initially_zero || memid->initially_committed);
375+
return p;
376+
}
377+
378+
379+
mi_decl_nodiscard static void* mi_os_ensure_zero(void* p, size_t size, mi_memid_t* memid) {
380+
if (p==NULL || size==0 || memid->initially_zero) return p;
381+
if (!memid->initially_committed) {
382+
bool is_zero = false;
383+
if (!_mi_os_commit(p, size, &is_zero)) {
384+
_mi_os_free(p, size, *memid);
385+
return NULL;
386+
}
387+
memid->initially_committed = true;
366388
}
389+
_mi_memzero_aligned(p,size);
390+
memid->initially_zero = true;
367391
return p;
368392
}
369393

394+
void* _mi_os_zalloc(size_t size, mi_memid_t* memid) {
395+
void* p = _mi_os_alloc(size,memid);
396+
return mi_os_ensure_zero(p, size, memid);
397+
}
398+
370399
/* -----------------------------------------------------------
371400
OS aligned allocation with an offset. This is used
372401
for large alignments > MI_BLOCK_ALIGNMENT_MAX. We use a large mimalloc

src/segment-map.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ static mi_segmap_part_t* mi_segment_map_index_of(const mi_segment_t* segment, bo
6161
if mi_unlikely(part == NULL) {
6262
if (!create_on_demand) return NULL;
6363
mi_memid_t memid;
64-
part = (mi_segmap_part_t*)_mi_os_alloc(sizeof(mi_segmap_part_t), &memid);
64+
part = (mi_segmap_part_t*)_mi_os_zalloc(sizeof(mi_segmap_part_t), &memid);
6565
if (part == NULL) return NULL;
6666
part->memid = memid;
6767
mi_segmap_part_t* expected = NULL;

0 commit comments

Comments
 (0)