summaryrefslogtreecommitdiffstats
path: root/src/chunk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/chunk.c')
-rw-r--r--src/chunk.c79
1 files changed, 47 insertions, 32 deletions
diff --git a/src/chunk.c b/src/chunk.c
index f8d9e63..59ebd29 100644
--- a/src/chunk.c
+++ b/src/chunk.c
@@ -586,51 +586,26 @@ static void
chunk_try_coalesce(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks,
extent_t *a, extent_t *b, extent_heap_t extent_heaps[NPSIZES], bool cache)
{
- rtree_elm_t *a_elm_a, *a_elm_b, *b_elm_a, *b_elm_b;
if (!chunk_can_coalesce(a, b))
return;
- if (chunk_hooks->merge(extent_addr_get(a), extent_size_get(a),
- extent_addr_get(b), extent_size_get(b), extent_committed_get(a),
- arena->ind))
- return;
-
- /*
- * The rtree writes must happen while all the relevant elements are
- * owned, so the following code uses decomposed helper functions rather
- * than chunk_{,de}register() to do things in the right order.
- */
- extent_rtree_acquire(tsdn, a, true, false, &a_elm_a, &a_elm_b);
- extent_rtree_acquire(tsdn, b, true, false, &b_elm_a, &b_elm_b);
-
- if (a_elm_b != NULL) {
- rtree_elm_write_acquired(tsdn, &chunks_rtree, a_elm_b, NULL);
- rtree_elm_release(tsdn, &chunks_rtree, a_elm_b);
- }
- if (b_elm_b != NULL) {
- rtree_elm_write_acquired(tsdn, &chunks_rtree, b_elm_a, NULL);
- rtree_elm_release(tsdn, &chunks_rtree, b_elm_a);
- } else
- b_elm_b = b_elm_a;
-
extent_heaps_remove(extent_heaps, a);
extent_heaps_remove(extent_heaps, b);
arena_chunk_cache_maybe_remove(extent_arena_get(a), a, cache);
arena_chunk_cache_maybe_remove(extent_arena_get(b), b, cache);
- extent_size_set(a, extent_size_get(a) + extent_size_get(b));
- extent_zeroed_set(a, extent_zeroed_get(a) && extent_zeroed_get(b));
+ if (chunk_merge_wrapper(tsdn, arena, chunk_hooks, a, b)) {
+ extent_heaps_insert(extent_heaps, a);
+ extent_heaps_insert(extent_heaps, b);
+ arena_chunk_cache_maybe_insert(extent_arena_get(a), a, cache);
+ arena_chunk_cache_maybe_insert(extent_arena_get(b), b, cache);
+ return;
+ }
extent_heaps_insert(extent_heaps, a);
-
- extent_rtree_write_acquired(tsdn, a_elm_a, b_elm_b, a);
- extent_rtree_release(tsdn, a_elm_a, b_elm_b);
-
arena_chunk_cache_maybe_insert(extent_arena_get(a), a, cache);
-
- arena_extent_dalloc(tsdn, extent_arena_get(b), b);
}
static void
@@ -821,6 +796,46 @@ chunk_merge_default(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b,
}
bool
+chunk_merge_wrapper(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks,
+ extent_t *a, extent_t *b)
+{
+ rtree_elm_t *a_elm_a, *a_elm_b, *b_elm_a, *b_elm_b;
+
+ if (chunk_hooks->merge(extent_addr_get(a), extent_size_get(a),
+ extent_addr_get(b), extent_size_get(b), extent_committed_get(a),
+ arena->ind))
+ return (true);
+
+ /*
+ * The rtree writes must happen while all the relevant elements are
+ * owned, so the following code uses decomposed helper functions rather
+ * than chunk_{,de}register() to do things in the right order.
+ */
+ extent_rtree_acquire(tsdn, a, true, false, &a_elm_a, &a_elm_b);
+ extent_rtree_acquire(tsdn, b, true, false, &b_elm_a, &b_elm_b);
+
+ if (a_elm_b != NULL) {
+ rtree_elm_write_acquired(tsdn, &chunks_rtree, a_elm_b, NULL);
+ rtree_elm_release(tsdn, &chunks_rtree, a_elm_b);
+ }
+ if (b_elm_b != NULL) {
+ rtree_elm_write_acquired(tsdn, &chunks_rtree, b_elm_a, NULL);
+ rtree_elm_release(tsdn, &chunks_rtree, b_elm_a);
+ } else
+ b_elm_b = b_elm_a;
+
+ extent_size_set(a, extent_size_get(a) + extent_size_get(b));
+ extent_zeroed_set(a, extent_zeroed_get(a) && extent_zeroed_get(b));
+
+ extent_rtree_write_acquired(tsdn, a_elm_a, b_elm_b, a);
+ extent_rtree_release(tsdn, a_elm_a, b_elm_b);
+
+ arena_extent_dalloc(tsdn, extent_arena_get(b), b);
+
+ return (false);
+}
+
+bool
chunk_boot(void)
{
#ifdef _WIN32