summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mimalloc.h2
-rw-r--r--src/init.c2
-rw-r--r--src/options.c8
-rw-r--r--src/os.c4
-rw-r--r--src/region.c2
-rw-r--r--src/segment.c2
6 files changed, 14 insertions, 6 deletions
diff --git a/include/mimalloc.h b/include/mimalloc.h
index 58ecaa6..c752ac2 100644
--- a/include/mimalloc.h
+++ b/include/mimalloc.h
@@ -327,6 +327,7 @@ typedef enum mi_option_e {
mi_option_os_tag,
mi_option_max_errors,
mi_option_max_warnings,
+ mi_option_max_segment_reclaim,
mi_option_allow_decommit,
mi_option_segment_decommit_delay,
mi_option_decommit_extend_delay,
@@ -341,6 +342,7 @@ mi_decl_export void mi_option_set_enabled(mi_option_t option, bool enable);
mi_decl_export void mi_option_set_enabled_default(mi_option_t option, bool enable);
mi_decl_nodiscard mi_decl_export long mi_option_get(mi_option_t option);
+mi_decl_nodiscard mi_decl_export long mi_option_get_clamp(mi_option_t option, long min, long max);
mi_decl_export void mi_option_set(mi_option_t option, long value);
mi_decl_export void mi_option_set_default(mi_option_t option, long value);
diff --git a/src/init.c b/src/init.c
index 69bd170..19124af 100644
--- a/src/init.c
+++ b/src/init.c
@@ -589,7 +589,7 @@ void mi_process_init(void) mi_attr_noexcept {
mi_stats_reset(); // only call stat reset *after* thread init (or the heap tld == NULL)
if (mi_option_is_enabled(mi_option_reserve_huge_os_pages)) {
- size_t pages = mi_option_get(mi_option_reserve_huge_os_pages);
+ size_t pages = mi_option_get_clamp(mi_option_reserve_huge_os_pages, 0, 128*1024);
long reserve_at = mi_option_get(mi_option_reserve_huge_os_pages_at);
if (reserve_at != -1) {
mi_reserve_huge_os_pages_at(pages, reserve_at, pages*500);
diff --git a/src/options.c b/src/options.c
index 7eb1eba..80feacf 100644
--- a/src/options.c
+++ b/src/options.c
@@ -93,7 +93,8 @@ static mi_option_desc_t options[_mi_option_last] =
{ 16, UNINIT, MI_OPTION(max_warnings) }, // maximum warnings that are output
{ 1, UNINIT, MI_OPTION(allow_decommit) }, // decommit slices when no longer used (after decommit_delay milli-seconds)
{ 500, UNINIT, MI_OPTION(segment_decommit_delay) }, // decommit delay in milli-seconds for freed segments
- { 2, UNINIT, MI_OPTION(decommit_extend_delay) }
+ { 2, UNINIT, MI_OPTION(decommit_extend_delay) },
+ { 8, UNINIT, MI_OPTION(max_segment_reclaim)},// max. number of segment reclaims from the abandoned segments per try.
};
static void mi_option_init(mi_option_desc_t* desc);
@@ -125,6 +126,11 @@ mi_decl_nodiscard long mi_option_get(mi_option_t option) {
return desc->value;
}
+mi_decl_nodiscard long mi_option_get_clamp(mi_option_t option, long min, long max) {
+ long x = mi_option_get(option);
+ return (x < min ? min : (x > max ? max : x));
+}
+
void mi_option_set(mi_option_t option, long value) {
mi_assert(option >= 0 && option < _mi_option_last);
if (option < 0 || option >= _mi_option_last) return;
diff --git a/src/os.c b/src/os.c
index 9d3bbb1..72959d8 100644
--- a/src/os.c
+++ b/src/os.c
@@ -364,7 +364,7 @@ static bool mi_os_mem_free(void* addr, size_t size, bool was_committed, mi_stats
// the start of the region.
MEMORY_BASIC_INFORMATION info = { 0, 0 };
VirtualQuery(addr, &info, sizeof(info));
- if (info.AllocationBase < addr) {
+ if (info.AllocationBase < addr && ((uint8_t*)addr - (uint8_t*)info.AllocationBase) < MI_SEGMENT_SIZE) {
errcode = 0;
err = (VirtualFree(info.AllocationBase, 0, MEM_RELEASE) == 0);
if (err) { errcode = GetLastError(); }
@@ -403,7 +403,7 @@ static void* mi_win_virtual_allocx(void* addr, size_t size, size_t try_alignment
if (hint != NULL) {
void* p = VirtualAlloc(hint, size, flags, PAGE_READWRITE);
if (p != NULL) return p;
- _mi_warning_message("unable to allocate hinted aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x)\n", size, GetLastError(), hint, try_alignment, flags);
+ _mi_verbose_message("warning: unable to allocate hinted aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x)\n", size, GetLastError(), hint, try_alignment, flags);
// fall through on error
}
}
diff --git a/src/region.c b/src/region.c
index 2d73025..72ce849 100644
--- a/src/region.c
+++ b/src/region.c
@@ -122,7 +122,7 @@ static size_t mi_good_commit_size(size_t size) {
*/
// Return if a pointer points into a region reserved by us.
-bool mi_is_in_heap_region(const void* p) mi_attr_noexcept {
+mi_decl_nodiscard bool mi_is_in_heap_region(const void* p) mi_attr_noexcept {
if (p==NULL) return false;
size_t count = mi_atomic_load_relaxed(&regions_count);
for (size_t i = 0; i < count; i++) {
diff --git a/src/segment.c b/src/segment.c
index 470632c..800d4fc 100644
--- a/src/segment.c
+++ b/src/segment.c
@@ -1364,7 +1364,7 @@ static mi_segment_t* mi_segment_try_reclaim(mi_heap_t* heap, size_t needed_slice
{
*reclaimed = false;
mi_segment_t* segment;
- int max_tries = 8; // limit the work to bound allocation times
+ long max_tries = mi_option_get_clamp(mi_option_max_segment_reclaim, 8, 1024); // limit the work to bound allocation times
while ((max_tries-- > 0) && ((segment = mi_abandoned_pop()) != NULL)) {
segment->abandoned_visits++;
bool has_page = mi_segment_check_free(segment,needed_slices,block_size,tld); // try to free up pages (due to concurrent frees)