From 4df01218e2f136d5eaaa443023331902dda51da5 Mon Sep 17 00:00:00 2001 From: daan Date: Sat, 5 Sep 2020 10:03:37 -0700 Subject: [PATCH] fix msvc compilation with new atomics --- include/mimalloc-atomic.h | 34 ++++++++++++++++++++++++++++++++++ include/mimalloc-types.h | 1 - src/arena.c | 12 ++++++------ test/main-override-static.c | 3 +++ 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/include/mimalloc-atomic.h b/include/mimalloc-atomic.h index e6f4ba0d..bb9430b0 100644 --- a/include/mimalloc-atomic.h +++ b/include/mimalloc-atomic.h @@ -106,6 +106,13 @@ static inline void mi_atomic_maxi64_relaxed(volatile int64_t* p, int64_t x) { while (current < x && !mi_atomic_cas_weak_release((_Atomic(int64_t)*)p, ¤t, x)) { /* nothing */ }; } +// Used by timers +#define mi_atomic_loadi64_acquire(p) mi_atomic(load_explicit)(p,mi_memory_order(acquire)) +#define mi_atomic_loadi64_relaxed(p) mi_atomic(load_explicit)(p,mi_memory_order(relaxed)) +#define mi_atomic_storei64_release(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(release)) +#define mi_atomic_storei64_relaxed(p,x) mi_atomic(store_explicit)(p,x,mi_memory_order(relaxed)) + + #elif defined(_MSC_VER) @@ -189,6 +196,27 @@ static inline void mi_atomic_store_explicit(_Atomic(uintptr_t)* p, uintptr_t x, mi_atomic_exchange_explicit(p,x,mo); #endif } +static inline int64_t mi_atomic_loadi64_explicit(_Atomic(int64_t)* p, mi_memory_order mo) { + (void)(mo); +#if defined(_M_X64) + return *p; +#else + int64_t old = *p; + int64_t x = old; + while ((old = InterlockedCompareExchange64(p, x, old)) != x) { + x = old; + } + return x; +#endif +} +static inline void mi_atomic_storei64_explicit(_Atomic(int64_t)* p, int64_t x, mi_memory_order mo) { + (void)(mo); +#if defined(x_M_IX86) || defined(_M_X64) + *p = x; +#else + InterlockedExchange64(p,x); +#endif +} // These are used by the statistics static inline int64_t mi_atomic_addi64_relaxed(volatile _Atomic(int64_t)* p, int64_t add) { @@ -222,6 +250,12 @@ static inline void mi_atomic_maxi64_relaxed(volatile _Atomic(int64_t)*p, int64_t #define mi_atomic_exchange_ptr_release(tp,p,x) (tp*)mi_atomic_exchange_release((_Atomic(uintptr_t)*)(p),(uintptr_t)x) #define mi_atomic_exchange_ptr_acq_rel(tp,p,x) (tp*)mi_atomic_exchange_acq_rel((_Atomic(uintptr_t)*)(p),(uintptr_t)x) +#define mi_atomic_loadi64_acquire(p) mi_atomic(loadi64_explicit)(p,mi_memory_order(acquire)) +#define mi_atomic_loadi64_relaxed(p) mi_atomic(loadi64_explicit)(p,mi_memory_order(relaxed)) +#define mi_atomic_storei64_release(p,x) mi_atomic(storei64_explicit)(p,x,mi_memory_order(release)) +#define mi_atomic_storei64_relaxed(p,x) mi_atomic(storei64_explicit)(p,x,mi_memory_order(relaxed)) + + #endif diff --git a/include/mimalloc-types.h b/include/mimalloc-types.h index d482240b..7270f798 100644 --- a/include/mimalloc-types.h +++ b/include/mimalloc-types.h @@ -280,7 +280,6 @@ typedef mi_page_t mi_slice_t; typedef int64_t mi_msecs_t; - // Segments are large allocated memory blocks (8mb on 64 bit) from // the OS. Inside segments we allocated fixed size _pages_ that // contain blocks. diff --git a/src/arena.c b/src/arena.c index 731d4e20..c7f38c2c 100644 --- a/src/arena.c +++ b/src/arena.c @@ -179,7 +179,7 @@ static void* mi_cache_pop(int numa_node, size_t size, size_t alignment, bool* co *is_zero = false; bool committed = slot->is_committed; slot->p = NULL; - mi_atomic_store_release(&slot->expire,(mi_msecs_t)0); + mi_atomic_storei64_release(&slot->expire,(mi_msecs_t)0); if (*commit && !committed) { bool commit_zero; _mi_os_commit(p, MI_SEGMENT_SIZE, &commit_zero, tld->stats); @@ -203,17 +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 if (idx >= MI_CACHE_MAX) idx = 0; // wrap mi_cache_slot_t* slot = &cache[idx]; - mi_msecs_t expire = mi_atomic_load_relaxed(&slot->expire); + mi_msecs_t expire = mi_atomic_loadi64_relaxed(&slot->expire); if (expire != 0 && now >= expire) { // racy read // seems expired, first claim it from available purged++; mi_bitmap_index_t bitidx = mi_bitmap_index_create_from_bit(idx); if (mi_bitmap_claim(cache_available, MI_CACHE_FIELDS, 1, bitidx, NULL)) { // was available, we claimed it - expire = mi_atomic_load_acquire(&slot->expire); + expire = mi_atomic_loadi64_acquire(&slot->expire); if (expire != 0 && now >= expire) { // safe read // still expired, decommit it - mi_atomic_store_relaxed(&slot->expire,(mi_msecs_t)0); + mi_atomic_storei64_relaxed(&slot->expire,(mi_msecs_t)0); 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_os_decommit(slot->p, MI_SEGMENT_SIZE, tld->stats); @@ -254,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)]; slot->p = start; slot->memid = memid; - mi_atomic_store_relaxed(&slot->expire,(mi_msecs_t)0); + mi_atomic_storei64_relaxed(&slot->expire,(mi_msecs_t)0); slot->is_committed = is_committed; if (is_committed && !is_large) { long delay = mi_option_get(mi_option_arena_reset_delay); @@ -264,7 +264,7 @@ static bool mi_cache_push(void* start, size_t size, size_t memid, bool is_commit slot->is_committed = false; } else { - mi_atomic_store_release(&slot->expire, _mi_clock_now() + delay); + mi_atomic_storei64_release(&slot->expire, _mi_clock_now() + delay); } } diff --git a/test/main-override-static.c b/test/main-override-static.c index ca65a0b2..0067be04 100644 --- a/test/main-override-static.c +++ b/test/main-override-static.c @@ -49,6 +49,7 @@ static inline uint8_t mi_bsr32(uint32_t x) { } #endif +/* // Bit scan reverse: return the index of the highest bit. uint8_t _mi_bsr(uintptr_t x) { if (x == 0) return 0; @@ -61,6 +62,8 @@ uint8_t _mi_bsr(uintptr_t x) { # error "define bsr for non-32 or 64-bit platforms" #endif } +*/ + static inline size_t _mi_wsize_from_size(size_t size) { return (size + sizeof(uintptr_t) - 1) / sizeof(uintptr_t);