Optimize extent coalescing.
Refactor extent_can_coalesce(), extent_coalesce(), and extent_record() to avoid needlessly repeating extent [de]activation operations.
This commit is contained in:
parent
b0654b95ed
commit
c1ebfaa673
43
src/extent.c
43
src/extent.c
@ -1020,14 +1020,19 @@ extent_alloc_wrapper(tsdn_t *tsdn, arena_t *arena,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
extent_can_coalesce(const extent_t *a, const extent_t *b) {
|
extent_can_coalesce(arena_t *arena, extents_t *extents, const extent_t *inner,
|
||||||
if (extent_arena_get(a) != extent_arena_get(b)) {
|
const extent_t *outer) {
|
||||||
|
assert(extent_arena_get(inner) == arena);
|
||||||
|
if (extent_arena_get(outer) != arena) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (extent_state_get(a) != extent_state_get(b)) {
|
|
||||||
|
assert(extent_state_get(inner) == extent_state_active);
|
||||||
|
if (extent_state_get(outer) != extents->state) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (extent_committed_get(a) != extent_committed_get(b)) {
|
|
||||||
|
if (extent_committed_get(inner) != extent_committed_get(outer)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1036,24 +1041,21 @@ extent_can_coalesce(const extent_t *a, const extent_t *b) {
|
|||||||
|
|
||||||
static bool
|
static bool
|
||||||
extent_coalesce(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks,
|
extent_coalesce(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks,
|
||||||
extent_t *a, extent_t *b, extents_t *extents) {
|
extents_t *extents, extent_t *inner, extent_t *outer, bool forward) {
|
||||||
assert(extent_can_coalesce(a, b));
|
assert(extent_can_coalesce(arena, extents, inner, outer));
|
||||||
assert(extent_arena_get(a) == arena);
|
|
||||||
assert(extent_arena_get(b) == arena);
|
|
||||||
|
|
||||||
extent_activate_locked(tsdn, arena, extents, a);
|
extent_activate_locked(tsdn, arena, extents, outer);
|
||||||
extent_activate_locked(tsdn, arena, extents, b);
|
|
||||||
|
|
||||||
malloc_mutex_unlock(tsdn, &extents->mtx);
|
malloc_mutex_unlock(tsdn, &extents->mtx);
|
||||||
bool err = extent_merge_wrapper(tsdn, arena, r_extent_hooks, a, b);
|
bool err = extent_merge_wrapper(tsdn, arena, r_extent_hooks,
|
||||||
|
forward ? inner : outer, forward ? outer : inner);
|
||||||
malloc_mutex_lock(tsdn, &extents->mtx);
|
malloc_mutex_lock(tsdn, &extents->mtx);
|
||||||
extent_deactivate_locked(tsdn, arena, extents, a);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
extent_deactivate_locked(tsdn, arena, extents, b);
|
extent_deactivate_locked(tsdn, arena, extents, outer);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1075,7 +1077,6 @@ extent_record(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks,
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert(extent_lookup(tsdn, extent_base_get(extent), true) == extent);
|
assert(extent_lookup(tsdn, extent_base_get(extent), true) == extent);
|
||||||
extent_deactivate_locked(tsdn, arena, extents, extent);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Continue attempting to coalesce until failure, to protect against
|
* Continue attempting to coalesce until failure, to protect against
|
||||||
@ -1098,10 +1099,10 @@ extent_record(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks,
|
|||||||
* before releasing the next_elm lock.
|
* before releasing the next_elm lock.
|
||||||
*/
|
*/
|
||||||
bool can_coalesce = (next != NULL &&
|
bool can_coalesce = (next != NULL &&
|
||||||
extent_can_coalesce(extent, next));
|
extent_can_coalesce(arena, extents, extent, next));
|
||||||
rtree_elm_release(tsdn, &extents_rtree, next_elm);
|
rtree_elm_release(tsdn, &extents_rtree, next_elm);
|
||||||
if (can_coalesce && !extent_coalesce(tsdn, arena,
|
if (can_coalesce && !extent_coalesce(tsdn, arena,
|
||||||
r_extent_hooks, extent, next, extents)) {
|
r_extent_hooks, extents, extent, next, true)) {
|
||||||
coalesced = true;
|
coalesced = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1114,16 +1115,18 @@ extent_record(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks,
|
|||||||
extent_t *prev = rtree_elm_read_acquired(tsdn,
|
extent_t *prev = rtree_elm_read_acquired(tsdn,
|
||||||
&extents_rtree, prev_elm);
|
&extents_rtree, prev_elm);
|
||||||
bool can_coalesce = (prev != NULL &&
|
bool can_coalesce = (prev != NULL &&
|
||||||
extent_can_coalesce(prev, extent));
|
extent_can_coalesce(arena, extents, extent, prev));
|
||||||
rtree_elm_release(tsdn, &extents_rtree, prev_elm);
|
rtree_elm_release(tsdn, &extents_rtree, prev_elm);
|
||||||
if (can_coalesce && !extent_coalesce(tsdn, arena,
|
if (can_coalesce && !extent_coalesce(tsdn, arena,
|
||||||
r_extent_hooks, prev, extent, extents)) {
|
r_extent_hooks, extents, extent, prev, false)) {
|
||||||
extent = prev;
|
extent = prev;
|
||||||
coalesced = true;
|
coalesced = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (coalesced);
|
} while (coalesced);
|
||||||
|
|
||||||
|
extent_deactivate_locked(tsdn, arena, extents, extent);
|
||||||
|
|
||||||
malloc_mutex_unlock(tsdn, &extents->mtx);
|
malloc_mutex_unlock(tsdn, &extents->mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user