From 18e02c3766d9fd8fc47fef2f0346645487d967ff Mon Sep 17 00:00:00 2001 From: daan Date: Tue, 27 Aug 2019 17:02:56 -0700 Subject: [PATCH] try allocating non-eager segments in non-fixed memory --- src/memory.c | 24 ++++++++++++++++++------ src/options.c | 2 +- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/memory.c b/src/memory.c index a9b87b8e..f53b1ec3 100644 --- a/src/memory.c +++ b/src/memory.c @@ -262,7 +262,7 @@ static bool mi_region_alloc_blocks(mem_region_t* region, size_t idx, size_t bloc mi_assert_internal((m >> bitidx) == mask); // no overflow? uintptr_t newmap = map | m; mi_assert_internal((newmap^map) >> bitidx == mask); - if (!mi_atomic_cas_weak(®ion->map, newmap, map)) { + if (!mi_atomic_cas_weak(®ion->map, newmap, map)) { // TODO: use strong cas here? // no success, another thread claimed concurrently.. keep going map = mi_atomic_read(®ion->map); continue; @@ -299,12 +299,24 @@ static bool mi_region_try_alloc_blocks(size_t idx, size_t blocks, size_t size, b mi_assert_internal(idx < MI_REGION_MAX); mem_region_t* region = ®ions[idx]; uintptr_t m = mi_atomic_read_relaxed(®ion->map); - if (m != MI_REGION_MAP_FULL) { // some bits are zero - return mi_region_alloc_blocks(region, idx, blocks, size, commit, large, p, id, tld); - } - else { - return true; // no error, but no success either + if (m != MI_REGION_MAP_FULL) { // some bits are zero + bool ok = (commit || *large); // committing or allow-large is always ok + if (!ok) { + // otherwise skip incompatible regions if possible. + // this is not guaranteed due to multiple threads allocating at the same time but + // that's ok. In secure mode, large is never allowed so that works out; otherwise + // we might just not be able to reset/decommit individual pages sometimes. + mi_region_info_t info = mi_atomic_read_relaxed(®ion->info); + bool is_large; + bool is_committed; + void* start = mi_region_info_read(info,&is_large,&is_committed); + ok = (start == NULL || (commit || !is_committed) || (*large || !is_large)); // Todo: test with one bitmap operation? + } + if (ok) { + return mi_region_alloc_blocks(region, idx, blocks, size, commit, large, p, id, tld); + } } + return true; // no error, but no success either } /* ---------------------------------------------------------------------------- diff --git a/src/options.c b/src/options.c index 1d030830..1076ce1e 100644 --- a/src/options.c +++ b/src/options.c @@ -60,7 +60,7 @@ static mi_option_desc_t options[_mi_option_last] = // the following options are experimental and not all combinations make sense. { 1, UNINIT, MI_OPTION(eager_commit) }, // note: needs to be on when eager_region_commit is enabled #ifdef _WIN32 // and BSD? - { 1, UNINIT, MI_OPTION(eager_region_commit) }, // don't commit too eagerly on windows (just for looks...) + { 0, UNINIT, MI_OPTION(eager_region_commit) }, // don't commit too eagerly on windows (just for looks...) #else { 1, UNINIT, MI_OPTION(eager_region_commit) }, #endif