From e03f26b0356090c657870f6446f7f8848c99b6ad Mon Sep 17 00:00:00 2001 From: daanx Date: Mon, 17 Apr 2023 11:39:55 -0700 Subject: [PATCH 1/3] fix atomic signature --- include/mimalloc/atomic.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mimalloc/atomic.h b/include/mimalloc/atomic.h index 857e9f02..61577833 100644 --- a/include/mimalloc/atomic.h +++ b/include/mimalloc/atomic.h @@ -290,8 +290,8 @@ typedef _Atomic(uintptr_t) mi_atomic_guard_t; #define mi_atomic_guard(guard) \ uintptr_t _mi_guard_expected = 0; \ for(bool _mi_guard_once = true; \ - _mi_guard_once && mi_atomic_cas_strong_acq_rel(guard,&_mi_guard_expected,1); \ - (mi_atomic_store_release(guard,0), _mi_guard_once = false) ) + _mi_guard_once && mi_atomic_cas_strong_acq_rel(guard,&_mi_guard_expected,(uintptr_t)1); \ + (mi_atomic_store_release(guard,(uintptr_t)0), _mi_guard_once = false) ) From 63ddc31d3f20738a9641b32fc99cf2187c35c20f Mon Sep 17 00:00:00 2001 From: daanx Date: Mon, 17 Apr 2023 12:01:00 -0700 Subject: [PATCH 2/3] fix 32-bit compile warnings --- include/mimalloc/atomic.h | 25 +++++++++++++++++++++---- src/arena.c | 6 +++--- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/include/mimalloc/atomic.h b/include/mimalloc/atomic.h index 61577833..d0226029 100644 --- a/include/mimalloc/atomic.h +++ b/include/mimalloc/atomic.h @@ -113,11 +113,13 @@ static inline void mi_atomic_maxi64_relaxed(volatile int64_t* p, int64_t x) { } // 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)) +#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)) +#define mi_atomic_casi64_strong_acq_rel(p,e,d) mi_atomic_cas_strong_acq_rel(p,e,d) +#define mi_atomic_addi64_acq_rel(p,i) mi_atomic_add_acq_rel(p,i) #elif defined(_MSC_VER) @@ -245,6 +247,21 @@ static inline void mi_atomic_maxi64_relaxed(volatile _Atomic(int64_t)*p, int64_t } while (current < x && _InterlockedCompareExchange64(p, x, current) != current); } +static inline void mi_atomic_addi64_acq_rel(volatile _Atomic(int64_t*)p, int64_t i) { + mi_atomic_addi64_relaxed(p, i); +} + +static inline bool mi_atomic_casi64_strong_acq_rel(volatile _Atomic(int64_t*)p, int64_t* exp, int64_t des) { + int64_t read = _InterlockedCompareExchange64(p, des, *exp); + if (read == *exp) { + return true; + } + else { + *exp = read; + return false; + } +} + // The pointer macros cast to `uintptr_t`. #define mi_atomic_load_ptr_acquire(tp,p) (tp*)mi_atomic_load_acquire((_Atomic(uintptr_t)*)(p)) #define mi_atomic_load_ptr_relaxed(tp,p) (tp*)mi_atomic_load_relaxed((_Atomic(uintptr_t)*)(p)) diff --git a/src/arena.c b/src/arena.c index f9b844bc..d3ffe3b7 100644 --- a/src/arena.c +++ b/src/arena.c @@ -506,7 +506,7 @@ static void mi_arena_schedule_purge(mi_arena_t* arena, size_t bitmap_idx, size_t // schedule decommit mi_msecs_t expire = mi_atomic_loadi64_relaxed(&arena->purge_expire); if (expire != 0) { - mi_atomic_add_acq_rel(&arena->purge_expire, delay/10); // add smallish extra delay + mi_atomic_addi64_acq_rel(&arena->purge_expire, delay/10); // add smallish extra delay } else { mi_atomic_storei64_release(&arena->purge_expire, _mi_clock_now() + delay); @@ -547,7 +547,7 @@ static bool mi_arena_try_purge(mi_arena_t* arena, mi_msecs_t now, bool force, mi if (!force && expire > now) return false; // reset expire (if not already set concurrently) - mi_atomic_cas_strong_acq_rel(&arena->purge_expire, &expire, 0); + mi_atomic_casi64_strong_acq_rel(&arena->purge_expire, &expire, 0); // potential purges scheduled, walk through the bitmap bool any_purged = false; @@ -589,7 +589,7 @@ static bool mi_arena_try_purge(mi_arena_t* arena, mi_msecs_t now, bool force, mi if (!full_purge) { const long delay = mi_option_get(mi_option_purge_delay) * mi_option_get(mi_option_arena_purge_mult); mi_msecs_t expected = 0; - mi_atomic_cas_strong_acq_rel(&arena->purge_expire,&expected,_mi_clock_now() + delay); + mi_atomic_casi64_strong_acq_rel(&arena->purge_expire,&expected,_mi_clock_now() + delay); } return any_purged; } From 72f3ba95a86b766d5aced3704fc8012b32cf87d9 Mon Sep 17 00:00:00 2001 From: Daan Leijen Date: Mon, 17 Apr 2023 12:08:22 -0700 Subject: [PATCH 3/3] reduce iterations under tsan --- test/test-stress.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/test-stress.c b/test/test-stress.c index c6236b77..c0de8910 100644 --- a/test/test-stress.c +++ b/test/test-stress.c @@ -26,7 +26,12 @@ terms of the MIT license. // argument defaults static int THREADS = 32; // more repeatable if THREADS <= #processors static int SCALE = 25; // scaling factor + +#if defined(MI_TSAN) +static int ITER = 10; // N full iterations destructing and re-creating all threads (on tsan reduce for azure pipeline limits) +#else static int ITER = 50; // N full iterations destructing and re-creating all threads +#endif // static int THREADS = 8; // more repeatable if THREADS <= #processors // static int SCALE = 100; // scaling factor