From 728be93977152e0be222a54e6247aa60415e60bc Mon Sep 17 00:00:00 2001 From: Daan Leijen Date: Thu, 17 Jun 2021 19:38:51 -0700 Subject: [PATCH 1/2] fix for #414 making numa node count atomic --- include/mimalloc-internal.h | 7 ++++--- src/os.c | 20 +++++++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/include/mimalloc-internal.h b/include/mimalloc-internal.h index 4a803ff5..1e1a7966 100644 --- a/include/mimalloc-internal.h +++ b/include/mimalloc-internal.h @@ -667,13 +667,14 @@ static inline uintptr_t _mi_random_shuffle(uintptr_t x) { int _mi_os_numa_node_get(mi_os_tld_t* tld); size_t _mi_os_numa_node_count_get(void); -extern size_t _mi_numa_node_count; +extern _Atomic(size_t) _mi_numa_node_count; static inline int _mi_os_numa_node(mi_os_tld_t* tld) { - if (mi_likely(_mi_numa_node_count == 1)) return 0; + if (mi_likely(mi_atomic_load_relaxed(&_mi_numa_node_count) == 1)) return 0; else return _mi_os_numa_node_get(tld); } static inline size_t _mi_os_numa_node_count(void) { - if (mi_likely(_mi_numa_node_count>0)) return _mi_numa_node_count; + const size_t count = mi_atomic_load_relaxed(&_mi_numa_node_count); + if (mi_likely(count>0)) return count; else return _mi_os_numa_node_count_get(); } diff --git a/src/os.c b/src/os.c index 5fed6b93..85415232 100644 --- a/src/os.c +++ b/src/os.c @@ -1202,17 +1202,23 @@ static size_t mi_os_numa_node_countx(void) { } #endif -size_t _mi_numa_node_count = 0; // cache the node count +_Atomic(size_t) _mi_numa_node_count; // = 0 // cache the node count size_t _mi_os_numa_node_count_get(void) { - if (mi_unlikely(_mi_numa_node_count <= 0)) { + size_t count = mi_atomic_load_acquire(&_mi_numa_node_count); + if (count <= 0) { long ncount = mi_option_get(mi_option_use_numa_nodes); // given explicitly? - if (ncount <= 0) ncount = (long)mi_os_numa_node_countx(); // or detect dynamically - _mi_numa_node_count = (size_t)(ncount <= 0 ? 1 : ncount); - _mi_verbose_message("using %zd numa regions\n", _mi_numa_node_count); + if (ncount > 0) { + count = (size_t)ncount; + } + else { + count = mi_os_numa_node_countx(); // or detect dynamically + if (count == 0) count = 1; + } + mi_atomic_store_release(&_mi_numa_node_count, count); // save it + _mi_verbose_message("using %zd numa regions\n", count); } - mi_assert_internal(_mi_numa_node_count >= 1); - return _mi_numa_node_count; + return count; } int _mi_os_numa_node_get(mi_os_tld_t* tld) { From 752594e76423526e108413731518a26e3322b9ca Mon Sep 17 00:00:00 2001 From: Daan Leijen Date: Thu, 17 Jun 2021 19:47:41 -0700 Subject: [PATCH 2/2] add test for #414 --- test/main-override.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/main-override.cpp b/test/main-override.cpp index 890b79a6..5fe3f9a3 100644 --- a/test/main-override.cpp +++ b/test/main-override.cpp @@ -33,6 +33,7 @@ void padding_shrink(); // issue #209 void various_tests(); void test_mt_shutdown(); void fail_aslr(); // issue #372 +void tsan_numa_test(); // issue #414 int main() { mi_stats_reset(); // ignore earlier allocations @@ -41,6 +42,8 @@ int main() { heap_late_free(); padding_shrink(); various_tests(); + tsan_numa_test(); + //test_mt_shutdown(); //fail_aslr(); mi_stats_print(NULL); @@ -216,4 +219,16 @@ void fail_aslr() { void* p = malloc(sz); printf("pointer p: %p: area up to %p\n", p, (uint8_t*)p + sz); *(int*)0x5FFFFFFF000 = 0; // should segfault +} + +// issues #414 +void dummy_worker() { + void* p = mi_malloc(0); + mi_free(p); +} + +void tsan_numa_test() { + auto t1 = std::thread(dummy_worker); + dummy_worker(); + t1.join(); } \ No newline at end of file