mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-07-03 10:14:37 +03:00
use atomic ops for the expire field; passes TSAN now
This commit is contained in:
parent
228b5f6e9d
commit
7058e501cb
1 changed files with 12 additions and 10 deletions
16
src/arena.c
16
src/arena.c
|
@ -135,7 +135,7 @@ static bool mi_arena_alloc(mi_arena_t* arena, size_t blocks, mi_bitmap_index_t*
|
||||||
typedef struct mi_cache_slot_s {
|
typedef struct mi_cache_slot_s {
|
||||||
void* p;
|
void* p;
|
||||||
size_t memid;
|
size_t memid;
|
||||||
mi_msecs_t expire;
|
_Atomic(mi_msecs_t) expire;
|
||||||
bool is_committed; // TODO: use bit from p to reduce size?
|
bool is_committed; // TODO: use bit from p to reduce size?
|
||||||
} mi_cache_slot_t;
|
} mi_cache_slot_t;
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ static void* mi_cache_pop(int numa_node, size_t size, size_t alignment, bool* co
|
||||||
*is_zero = false;
|
*is_zero = false;
|
||||||
bool committed = slot->is_committed;
|
bool committed = slot->is_committed;
|
||||||
slot->p = NULL;
|
slot->p = NULL;
|
||||||
slot->expire = 0;
|
mi_atomic_store_release(&slot->expire,0);
|
||||||
if (*commit && !committed) {
|
if (*commit && !committed) {
|
||||||
bool commit_zero;
|
bool commit_zero;
|
||||||
_mi_os_commit(p, MI_SEGMENT_SIZE, &commit_zero, tld->stats);
|
_mi_os_commit(p, MI_SEGMENT_SIZE, &commit_zero, tld->stats);
|
||||||
|
@ -203,15 +203,17 @@ static void mi_cache_purge(mi_os_tld_t* tld) {
|
||||||
for (size_t visited = 0; visited < MI_CACHE_FIELDS; visited++,idx++) { // probe just N slots
|
for (size_t visited = 0; visited < MI_CACHE_FIELDS; visited++,idx++) { // probe just N slots
|
||||||
if (idx >= MI_CACHE_MAX) idx = 0; // wrap
|
if (idx >= MI_CACHE_MAX) idx = 0; // wrap
|
||||||
mi_cache_slot_t* slot = &cache[idx];
|
mi_cache_slot_t* slot = &cache[idx];
|
||||||
if (slot->expire != 0 && now >= slot->expire) { // racy read
|
mi_msecs_t expire = mi_atomic_load_relaxed(&slot->expire);
|
||||||
|
if (expire != 0 && now >= expire) { // racy read
|
||||||
// seems expired, first claim it from available
|
// seems expired, first claim it from available
|
||||||
purged++;
|
purged++;
|
||||||
mi_bitmap_index_t bitidx = mi_bitmap_index_create_from_bit(idx);
|
mi_bitmap_index_t bitidx = mi_bitmap_index_create_from_bit(idx);
|
||||||
if (mi_bitmap_claim(cache_available, MI_CACHE_FIELDS, 1, bitidx, NULL)) {
|
if (mi_bitmap_claim(cache_available, MI_CACHE_FIELDS, 1, bitidx, NULL)) {
|
||||||
// was available, we claimed it
|
// was available, we claimed it
|
||||||
if (slot->expire != 0 && now >= slot->expire) { // safe read
|
expire = mi_atomic_load_acquire(&slot->expire);
|
||||||
|
if (expire != 0 && now >= expire) { // safe read
|
||||||
// still expired, decommit it
|
// still expired, decommit it
|
||||||
slot->expire = 0;
|
mi_atomic_store_relaxed(&slot->expire,0);
|
||||||
mi_assert_internal(slot->is_committed && mi_bitmap_is_claimed(cache_available_large, MI_CACHE_FIELDS, 1, bitidx));
|
mi_assert_internal(slot->is_committed && mi_bitmap_is_claimed(cache_available_large, MI_CACHE_FIELDS, 1, bitidx));
|
||||||
_mi_abandoned_await_readers(); // wait until safe to decommit
|
_mi_abandoned_await_readers(); // wait until safe to decommit
|
||||||
_mi_os_decommit(slot->p, MI_SEGMENT_SIZE, tld->stats);
|
_mi_os_decommit(slot->p, MI_SEGMENT_SIZE, tld->stats);
|
||||||
|
@ -252,7 +254,7 @@ static bool mi_cache_push(void* start, size_t size, size_t memid, bool is_commit
|
||||||
mi_cache_slot_t* slot = &cache[mi_bitmap_index_bit(bitidx)];
|
mi_cache_slot_t* slot = &cache[mi_bitmap_index_bit(bitidx)];
|
||||||
slot->p = start;
|
slot->p = start;
|
||||||
slot->memid = memid;
|
slot->memid = memid;
|
||||||
slot->expire = 0;
|
mi_atomic_store_relaxed(&slot->expire,0);
|
||||||
slot->is_committed = is_committed;
|
slot->is_committed = is_committed;
|
||||||
if (is_committed && !is_large) {
|
if (is_committed && !is_large) {
|
||||||
long delay = mi_option_get(mi_option_arena_reset_delay);
|
long delay = mi_option_get(mi_option_arena_reset_delay);
|
||||||
|
@ -262,7 +264,7 @@ static bool mi_cache_push(void* start, size_t size, size_t memid, bool is_commit
|
||||||
slot->is_committed = false;
|
slot->is_committed = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
slot->expire = _mi_clock_now() + delay;
|
mi_atomic_store_release(&slot->expire, _mi_clock_now() + delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue