Skip to content

Commit f35b4f4

Browse files
committed
Merge branch 'dev' into dev2
2 parents 98c2bd2 + 57830a4 commit f35b4f4

File tree

7 files changed

+64
-43
lines changed

7 files changed

+64
-43
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
@@ -192,14 +192,9 @@ void* _mi_arena_meta_zalloc(size_t size, mi_memid_t* memid) {
192192
if (p != NULL) return p;
193193

194194
// or fall back to the OS
195-
p = _mi_os_alloc(size, memid);
195+
p = _mi_os_zalloc(size, memid);
196196
if (p == NULL) return NULL;
197197

198-
// zero the OS memory if needed
199-
if (!memid->initially_zero) {
200-
_mi_memzero_aligned(p, size);
201-
memid->initially_zero = true;
202-
}
203198
return p;
204199
}
205200

src/init.c

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

318318
static mi_thread_data_t* mi_thread_data_zalloc(void) {
319319
// try to find thread metadata in the cache
320-
bool is_zero = false;
321320
mi_thread_data_t* td = NULL;
322321
for (int i = 0; i < TD_CACHE_SIZE; i++) {
323322
td = mi_atomic_load_ptr_relaxed(mi_thread_data_t, &td_cache[i]);
324323
if (td != NULL) {
325324
// found cached allocation, try use it
326325
td = mi_atomic_exchange_ptr_acq_rel(mi_thread_data_t, &td_cache[i], NULL);
327326
if (td != NULL) {
328-
break;
327+
_mi_memzero(td, offsetof(mi_thread_data_t,memid));
328+
return td;
329329
}
330330
}
331331
}
332332

333333
// if that fails, allocate as meta data
334+
mi_memid_t memid;
335+
td = (mi_thread_data_t*)_mi_os_zalloc(sizeof(mi_thread_data_t), &memid);
334336
if (td == NULL) {
335-
mi_memid_t memid;
336-
td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &memid);
337+
// if this fails, try once more. (issue #257)
338+
td = (mi_thread_data_t*)_mi_os_zalloc(sizeof(mi_thread_data_t), &memid);
337339
if (td == NULL) {
338-
// if this fails, try once more. (issue #257)
339-
td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &memid);
340-
if (td == NULL) {
341-
// really out of memory
342-
_mi_error_message(ENOMEM, "unable to allocate thread local heap metadata (%zu bytes)\n", sizeof(mi_thread_data_t));
343-
}
344-
}
345-
if (td != NULL) {
346-
td->memid = memid;
347-
is_zero = memid.initially_zero;
340+
// really out of memory
341+
_mi_error_message(ENOMEM, "unable to allocate thread local heap metadata (%zu bytes)\n", sizeof(mi_thread_data_t));
342+
return NULL;
348343
}
349344
}
350-
351-
if (td != NULL && !is_zero) {
352-
_mi_memzero_aligned(td, offsetof(mi_thread_data_t,memid));
353-
}
345+
td->memid = memid;
354346
return td;
355347
}
356348

src/os.c

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ void _mi_os_free_ex(void* addr, size_t size, bool still_committed, mi_memid_t me
167167
if (mi_memkind_is_os(memid.memkind)) {
168168
size_t csize = memid.mem.os.size;
169169
if (csize==0) { csize = _mi_os_good_alloc_size(size); }
170+
mi_assert_internal(csize >= size);
170171
size_t commit_size = (still_committed ? csize : 0);
171172
void* base = addr;
172173
// different base? (due to alignment)
@@ -326,9 +327,11 @@ void* _mi_os_alloc(size_t size, mi_memid_t* memid) {
326327
bool os_is_large = false;
327328
bool os_is_zero = false;
328329
void* p = mi_os_prim_alloc(size, 0, true, false, &os_is_large, &os_is_zero);
329-
if (p != NULL) {
330-
*memid = _mi_memid_create_os(p, size, true, os_is_zero, os_is_large);
331-
}
330+
if (p == NULL) return NULL;
331+
332+
*memid = _mi_memid_create_os(p, size, true, os_is_zero, os_is_large);
333+
mi_assert_internal(memid->mem.os.size >= size);
334+
mi_assert_internal(memid->initially_committed);
332335
return p;
333336
}
334337

@@ -344,14 +347,43 @@ void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allo
344347
bool os_is_zero = false;
345348
void* os_base = NULL;
346349
void* p = mi_os_prim_alloc_aligned(size, alignment, commit, allow_large, &os_is_large, &os_is_zero, &os_base );
347-
if (p != NULL) {
348-
*memid = _mi_memid_create_os(p, size, commit, os_is_zero, os_is_large);
349-
memid->mem.os.base = os_base;
350-
memid->mem.os.size += ((uint8_t*)p - (uint8_t*)os_base); // todo: return from prim_alloc_aligned?
350+
if (p == NULL) return NULL;
351+
352+
*memid = _mi_memid_create_os(p, size, commit, os_is_zero, os_is_large);
353+
memid->mem.os.base = os_base;
354+
memid->mem.os.size += ((uint8_t*)p - (uint8_t*)os_base); // todo: return from prim_alloc_aligned?
355+
356+
mi_assert_internal(memid->mem.os.size >= size);
357+
mi_assert_internal(_mi_is_aligned(p,alignment));
358+
if (commit) { mi_assert_internal(memid->initially_committed); }
359+
if (memid->initially_zero) { mi_assert_internal(memid->initially_committed); }
360+
return p;
361+
}
362+
363+
364+
mi_decl_nodiscard static void* mi_os_ensure_zero(void* p, size_t size, mi_memid_t* memid) {
365+
if (p==NULL || size==0) return p;
366+
// ensure committed
367+
if (!memid->initially_committed) {
368+
bool is_zero = false;
369+
if (!_mi_os_commit(p, size, &is_zero)) {
370+
_mi_os_free(p, size, *memid);
371+
return NULL;
372+
}
373+
memid->initially_committed = true;
351374
}
375+
// ensure zero'd
376+
if (memid->initially_zero) return p;
377+
_mi_memzero_aligned(p,size);
378+
memid->initially_zero = true;
352379
return p;
353380
}
354381

382+
void* _mi_os_zalloc(size_t size, mi_memid_t* memid) {
383+
void* p = _mi_os_alloc(size,memid);
384+
return mi_os_ensure_zero(p, size, memid);
385+
}
386+
355387
/* -----------------------------------------------------------
356388
OS aligned allocation with an offset. This is used
357389
for large alignments > MI_BLOCK_ALIGNMENT_MAX. We use a large mimalloc

src/prim/unix/prim.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ int _mi_prim_commit(void* start, size_t size, bool* is_zero) {
430430
}
431431

432432
int _mi_prim_reuse(void* start, size_t size) {
433+
MI_UNUSED(start); MI_UNUSED(size);
433434
#if defined(__APPLE__) && defined(MADV_FREE_REUSE)
434435
return unix_madvise(start, size, MADV_FREE_REUSE);
435436
#endif
@@ -438,18 +439,17 @@ int _mi_prim_reuse(void* start, size_t size) {
438439

439440
int _mi_prim_decommit(void* start, size_t size, bool* needs_recommit) {
440441
int err = 0;
441-
#if !MI_DEBUG && MI_SECURE<=2
442-
*needs_recommit = false;
443-
#if defined(__APPLE__) && defined(MADV_FREE_REUSABLE)
442+
#if defined(__APPLE__) && defined(MADV_FREE_REUSABLE)
444443
// decommit on macOS: use MADV_FREE_REUSABLE as it does immediate rss accounting (issue #1097)
445444
err = unix_madvise(start, size, MADV_FREE_REUSABLE);
446-
#else
445+
if (err) { err = unix_madvise(start, size, MADV_DONTNEED); }
446+
#else
447447
// decommit: use MADV_DONTNEED as it decreases rss immediately (unlike MADV_FREE)
448448
err = unix_madvise(start, size, MADV_DONTNEED);
449-
#endif
449+
#endif
450+
#if !MI_DEBUG && MI_SECURE<=2
451+
*needs_recommit = false;
450452
#else
451-
// note: don't use MADV_FREE_REUSABLE as the range may contain protected areas
452-
err = unix_madvise(start, size, MADV_DONTNEED);
453453
*needs_recommit = true;
454454
mprotect(start, size, PROT_NONE);
455455
#endif
@@ -465,10 +465,11 @@ int _mi_prim_decommit(void* start, size_t size, bool* needs_recommit) {
465465

466466
int _mi_prim_reset(void* start, size_t size) {
467467
int err = 0;
468-
#if defined(__APPLE__) && defined(MADV_FREE_REUSABLE)
469-
// on macOS we try to use MADV_FREE_REUSABLE as it seems the fastest
468+
469+
// on macOS can use MADV_FREE_REUSABLE (but we disable this for now as it seems slower)
470+
#if 0 && defined(__APPLE__) && defined(MADV_FREE_REUSABLE)
470471
err = unix_madvise(start, size, MADV_FREE_REUSABLE);
471-
if (err == 0) return 0;
472+
if (err==0) return 0;
472473
// fall through
473474
#endif
474475

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)