From e68010573fb2b4149b48324bf305a1f13e490750 Mon Sep 17 00:00:00 2001 From: Trout Zhang Date: Sun, 23 Apr 2023 21:39:20 +0800 Subject: [PATCH 1/3] Fix ATOMIC_VAR_INIT deprecation warnings for C17 --- include/mimalloc/atomic.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/mimalloc/atomic.h b/include/mimalloc/atomic.h index d0226029..bd95dd5f 100644 --- a/include/mimalloc/atomic.h +++ b/include/mimalloc/atomic.h @@ -39,7 +39,11 @@ terms of the MIT license. A copy of the license can be found in the file #include #define mi_atomic(name) atomic_##name #define mi_memory_order(name) memory_order_##name -#define MI_ATOMIC_VAR_INIT(x) ATOMIC_VAR_INIT(x) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201710L) // c17, see issue #735 + #define MI_ATOMIC_VAR_INIT(x) x +#else + #define MI_ATOMIC_VAR_INIT(x) ATOMIC_VAR_INIT(x) +#endif #endif // Various defines for all used memory orders in mimalloc From 67dcbbfa43bf3d9300b4880fea0296cbb4f58a2a Mon Sep 17 00:00:00 2001 From: daanx Date: Sun, 23 Apr 2023 12:46:38 -0700 Subject: [PATCH 2/3] refine c17 check for ATOMIC_VAR_INIT --- include/mimalloc/atomic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mimalloc/atomic.h b/include/mimalloc/atomic.h index bd95dd5f..fe418fab 100644 --- a/include/mimalloc/atomic.h +++ b/include/mimalloc/atomic.h @@ -39,7 +39,7 @@ terms of the MIT license. A copy of the license can be found in the file #include #define mi_atomic(name) atomic_##name #define mi_memory_order(name) memory_order_##name -#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201710L) // c17, see issue #735 +#if !defined(ATOMIC_VAR_INIT) || (__STDC_VERSION__ >= 201710L) // c17, see issue #735 #define MI_ATOMIC_VAR_INIT(x) x #else #define MI_ATOMIC_VAR_INIT(x) ATOMIC_VAR_INIT(x) From a59ae585c785b18cdf3473a9d04ae8fccc709eee Mon Sep 17 00:00:00 2001 From: daanx Date: Sun, 23 Apr 2023 13:04:50 -0700 Subject: [PATCH 3/3] remove allow_purge option --- include/mimalloc.h | 41 ++++++++++++++++++++--------------------- src/arena.c | 7 ++++--- src/options.c | 1 - src/os.c | 6 +++--- src/segment.c | 4 ++-- 5 files changed, 29 insertions(+), 30 deletions(-) diff --git a/include/mimalloc.h b/include/mimalloc.h index 9cc2afba..368c22cc 100644 --- a/include/mimalloc.h +++ b/include/mimalloc.h @@ -319,32 +319,31 @@ typedef enum mi_option_e { mi_option_show_stats, // print statistics on termination mi_option_verbose, // print verbose messages // the following options are experimental (see src/options.h) - mi_option_eager_commit, - mi_option_arena_eager_commit, - mi_option_purge_decommits, - mi_option_allow_large_os_pages, // enable large (2MiB) OS pages, implies eager commit - mi_option_reserve_huge_os_pages, // reserve N huge OS pages (1GiB) at startup + mi_option_eager_commit, // eager commit segments? (after `eager_commit_delay` segments) (=1) + mi_option_arena_eager_commit, // eager commit arenas? Use 2 to enable just on overcommit systems (=2) + mi_option_purge_decommits, // should a memory purge decommit (or only reset) (=1) + mi_option_allow_large_os_pages, // allow large (2MiB) OS pages, implies eager commit + mi_option_reserve_huge_os_pages, // reserve N huge OS pages (1GiB/page) at startup mi_option_reserve_huge_os_pages_at, // reserve huge OS pages at a specific NUMA node - mi_option_reserve_os_memory, // reserve specified amount of OS memory at startup + mi_option_reserve_os_memory, // reserve specified amount of OS memory in an arena at startup mi_option_deprecated_segment_cache, mi_option_deprecated_page_reset, - mi_option_abandoned_page_purge, - mi_option_deprecated_segment_reset, - mi_option_eager_commit_delay, - mi_option_purge_delay, - mi_option_use_numa_nodes, // 0 = use available numa nodes, otherwise use at most N nodes. - mi_option_limit_os_alloc, // 1 = do not use OS memory for allocation (but only reserved arenas) - mi_option_os_tag, - mi_option_max_errors, - mi_option_max_warnings, - mi_option_max_segment_reclaim, - mi_option_destroy_on_exit, - mi_option_arena_reserve, - mi_option_arena_purge_mult, - mi_option_allow_purge, + mi_option_abandoned_page_purge, // immediately purge delayed purges on thread termination + mi_option_deprecated_segment_reset, + mi_option_eager_commit_delay, + mi_option_purge_delay, // memory purging is delayed by N milli seconds; use 0 for immediate purging or -1 for no purging at all. + mi_option_use_numa_nodes, // 0 = use all available numa nodes, otherwise use at most N nodes. + mi_option_limit_os_alloc, // 1 = do not use OS memory for allocation (but only programmatically reserved arenas) + mi_option_os_tag, // tag used for OS logging (macOS only for now) + mi_option_max_errors, // issue at most N error messages + mi_option_max_warnings, // issue at most N warning messages + mi_option_max_segment_reclaim, + mi_option_destroy_on_exit, // if set, release all memory on exit; sometimes used for dynamic unloading but can be unsafe. + mi_option_arena_reserve, // initial memory size in KiB for arena reservation (1GiB on 64-bit) + mi_option_arena_purge_mult, mi_option_purge_extend_delay, _mi_option_last, - // legacy options + // legacy option names mi_option_large_os_pages = mi_option_allow_large_os_pages, mi_option_eager_region_commit = mi_option_arena_eager_commit, mi_option_reset_decommits = mi_option_purge_decommits, diff --git a/src/arena.c b/src/arena.c index ec5e5d6f..299cc231 100644 --- a/src/arena.c +++ b/src/arena.c @@ -422,6 +422,7 @@ void* mi_arena_area(mi_arena_id_t arena_id, size_t* size) { ----------------------------------------------------------- */ static long mi_arena_purge_delay(void) { + // <0 = no purging allowed, 0=immediate purging, >0=milli-second delay return (mi_option_get(mi_option_purge_delay) * mi_option_get(mi_option_arena_purge_mult)); } @@ -460,9 +461,9 @@ static void mi_arena_purge(mi_arena_t* arena, size_t bitmap_idx, size_t blocks, // Note: assumes we (still) own the area as we may purge immediately static void mi_arena_schedule_purge(mi_arena_t* arena, size_t bitmap_idx, size_t blocks, mi_stats_t* stats) { mi_assert_internal(arena->blocks_purge != NULL); - if (!mi_option_is_enabled(mi_option_allow_purge)) return; - const long delay = mi_arena_purge_delay(); + if (delay < 0) return; // is purging allowed at all? + if (_mi_preloading() || delay == 0) { // decommit directly mi_arena_purge(arena, bitmap_idx, blocks, stats); @@ -563,7 +564,7 @@ static bool mi_arena_try_purge(mi_arena_t* arena, mi_msecs_t now, bool force, mi } static void mi_arenas_try_purge( bool force, bool visit_all, mi_stats_t* stats ) { - if (_mi_preloading() || !mi_option_is_enabled(mi_option_allow_purge) || mi_arena_purge_delay() == 0) return; // nothing will be scheduled + if (_mi_preloading() || mi_arena_purge_delay() <= 0) return; // nothing will be scheduled const size_t max_arena = mi_atomic_load_acquire(&mi_arena_count); if (max_arena == 0) return; diff --git a/src/options.c b/src/options.c index 3bbb18e8..f52af8b8 100644 --- a/src/options.c +++ b/src/options.c @@ -90,7 +90,6 @@ static mi_option_desc_t options[_mi_option_last] = #endif { 10, UNINIT, MI_OPTION(arena_purge_mult) }, // purge delay multiplier for arena's - { 1, UNINIT, MI_OPTION(allow_purge) }, // allow decommit/reset to free (physical) memory back to the OS { 1, UNINIT, MI_OPTION_LEGACY(purge_extend_delay, decommit_extend_delay) }, }; diff --git a/src/os.c b/src/os.c index 1b435335..97a9f46d 100644 --- a/src/os.c +++ b/src/os.c @@ -473,14 +473,14 @@ bool _mi_os_reset(void* addr, size_t size, mi_stats_t* stats) { // to be recommitted if it is to be re-used later on. bool _mi_os_purge_ex(void* p, size_t size, bool allow_reset, mi_stats_t* stats) { - if (!mi_option_is_enabled(mi_option_allow_purge)) return false; + if (mi_option_get(mi_option_purge_delay) < 0) return false; // is purging allowed? _mi_stat_counter_increase(&stats->purge_calls, 1); _mi_stat_increase(&stats->purged, size); if (mi_option_is_enabled(mi_option_purge_decommits) && // should decommit? !_mi_preloading()) // don't decommit during preloading (unsafe) { - bool needs_recommit; + bool needs_recommit = true; mi_os_decommit_ex(p, size, &needs_recommit, stats); return needs_recommit; } @@ -488,7 +488,7 @@ bool _mi_os_purge_ex(void* p, size_t size, bool allow_reset, mi_stats_t* stats) if (allow_reset) { // this can sometimes be not allowed if the range is not fully committed _mi_os_reset(p, size, stats); } - return false; // not decommitted + return false; // needs no recommit } } diff --git a/src/segment.c b/src/segment.c index 359bd258..5635b45c 100644 --- a/src/segment.c +++ b/src/segment.c @@ -347,7 +347,7 @@ static void mi_segment_remove_all_purges(mi_segment_t* segment, bool force_purge } static void mi_pages_try_purge(mi_segments_tld_t* tld) { - if (!mi_option_is_enabled(mi_option_allow_purge)) return; + if (mi_option_get(mi_option_purge_delay) < 0) return; // purging is not allowed mi_msecs_t now = _mi_clock_now(); mi_page_queue_t* pq = &tld->pages_purge; @@ -542,7 +542,7 @@ static mi_segment_t* mi_segment_os_alloc(bool eager_delayed, size_t page_alignme mi_track_mem_undefined(segment, info_size); MI_UNUSED(info_size); segment->memid = memid; segment->allow_decommit = !memid.is_pinned; - segment->allow_purge = segment->allow_decommit && mi_option_is_enabled(mi_option_allow_purge); + segment->allow_purge = segment->allow_decommit && (mi_option_get(mi_option_purge_delay) >= 0); segment->segment_size = segment_size; mi_segments_track_size((long)(segment_size), tld); _mi_segment_map_allocated_at(segment);