diff --git a/include/mimalloc-types.h b/include/mimalloc-types.h index 9beeb195..67ad8516 100644 --- a/include/mimalloc-types.h +++ b/include/mimalloc-types.h @@ -384,6 +384,7 @@ typedef struct mi_segments_tld_s { // OS thread local data typedef struct mi_os_tld_s { + size_t region_idx; // start point for next allocation mi_stats_t* stats; // points to tld stats } mi_os_tld_t; diff --git a/src/init.c b/src/init.c index 0261e26b..77ce4aad 100644 --- a/src/init.c +++ b/src/init.c @@ -97,7 +97,7 @@ static mi_tld_t tld_main = { 0, &_mi_heap_main, { { NULL, NULL }, {NULL ,NULL}, 0, 0, 0, 0, 0, 0, NULL, tld_main_stats }, // segments - { tld_main_stats }, // os + { 0, tld_main_stats }, // os { MI_STATS_NULL } // stats }; diff --git a/src/memory.c b/src/memory.c index ccd810b3..cf341105 100644 --- a/src/memory.c +++ b/src/memory.c @@ -79,7 +79,6 @@ typedef struct mem_region_s { static mem_region_t regions[MI_REGION_MAX]; static volatile size_t regions_count = 0; // allocated regions -static volatile uintptr_t region_next_idx = 0; // good place to start searching /* ---------------------------------------------------------------------------- @@ -180,7 +179,6 @@ static bool mi_region_commit_blocks(mem_region_t* region, size_t idx, size_t bit } // and return the allocation - mi_atomic_write(®ion_next_idx,idx); // next search from here *p = blocks_start; *id = (idx*MI_REGION_MAP_BITS) + bitidx; return true; @@ -267,7 +265,7 @@ void* _mi_mem_alloc_aligned(size_t size, size_t alignment, bool commit, size_t* // find a range of free blocks void* p = NULL; size_t count = mi_atomic_read(®ions_count); - size_t idx = mi_atomic_read(®ion_next_idx); + size_t idx = tld->region_idx; // start index is per-thread to reduce contention for (size_t visited = 0; visited < count; visited++, idx++) { if (idx >= count) idx = 0; // wrap around if (!mi_region_try_alloc_blocks(idx, blocks, size, commit, &p, id, tld)) return NULL; // error @@ -286,6 +284,9 @@ void* _mi_mem_alloc_aligned(size_t size, size_t alignment, bool commit, size_t* // we could not find a place to allocate, fall back to the os directly p = _mi_os_alloc_aligned(size, alignment, commit, tld); } + else { + tld->region_idx = idx; // next start of search + } mi_assert_internal( p == NULL || (uintptr_t)p % alignment == 0); return p;