Skip to content

Commit 52fc887

Browse files
committed
Avoid inactivity_check within background threads.
Passing is_background_thread down the decay path, so that background thread itself won't attempt inactivity_check. This fixes an issue with background thread doing trylock on a mutex it already owns.
1 parent 37f3fa0 commit 52fc887

File tree

2 files changed

+25
-19
lines changed

2 files changed

+25
-19
lines changed

include/jemalloc/internal/background_thread_inlines.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ background_thread_indefinite_sleep(background_thread_info_t *info) {
4141
}
4242

4343
JEMALLOC_ALWAYS_INLINE void
44-
arena_background_thread_inactivity_check(tsdn_t *tsdn, arena_t *arena) {
45-
if (!background_thread_enabled()) {
44+
arena_background_thread_inactivity_check(tsdn_t *tsdn, arena_t *arena,
45+
bool is_background_thread) {
46+
if (!background_thread_enabled() || is_background_thread) {
4647
return;
4748
}
4849
background_thread_info_t *info =

src/arena.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ const uint64_t h_steps[SMOOTHSTEP_NSTEPS] = {
6161
*/
6262

6363
static void arena_decay_to_limit(tsdn_t *tsdn, arena_t *arena,
64-
arena_decay_t *decay, extents_t *extents, bool all, size_t npages_limit);
64+
arena_decay_t *decay, extents_t *extents, bool all, size_t npages_limit,
65+
bool is_background_thread);
6566
static bool arena_decay_dirty(tsdn_t *tsdn, arena_t *arena,
6667
bool is_background_thread, bool all);
6768
static void arena_dalloc_bin_slab(tsdn_t *tsdn, arena_t *arena, extent_t *slab,
@@ -378,7 +379,7 @@ arena_extents_dirty_dalloc(tsdn_t *tsdn, arena_t *arena,
378379
if (arena_dirty_decay_ms_get(arena) == 0) {
379380
arena_decay_dirty(tsdn, arena, false, true);
380381
} else {
381-
arena_background_thread_inactivity_check(tsdn, arena);
382+
arena_background_thread_inactivity_check(tsdn, arena, false);
382383
}
383384
}
384385

@@ -687,10 +688,11 @@ arena_decay_backlog_update(arena_decay_t *decay, uint64_t nadvance_u64,
687688

688689
static void
689690
arena_decay_try_purge(tsdn_t *tsdn, arena_t *arena, arena_decay_t *decay,
690-
extents_t *extents, size_t current_npages, size_t npages_limit) {
691+
extents_t *extents, size_t current_npages, size_t npages_limit,
692+
bool is_background_thread) {
691693
if (current_npages > npages_limit) {
692694
arena_decay_to_limit(tsdn, arena, decay, extents, false,
693-
npages_limit);
695+
npages_limit, is_background_thread);
694696
}
695697
}
696698

@@ -720,17 +722,18 @@ arena_decay_epoch_advance_helper(arena_decay_t *decay, const nstime_t *time,
720722

721723
static void
722724
arena_decay_epoch_advance(tsdn_t *tsdn, arena_t *arena, arena_decay_t *decay,
723-
extents_t *extents, const nstime_t *time, bool purge) {
725+
extents_t *extents, const nstime_t *time, bool is_background_thread) {
724726
size_t current_npages = extents_npages_get(extents);
725727
arena_decay_epoch_advance_helper(decay, time, current_npages);
726728

727729
size_t npages_limit = arena_decay_backlog_npages_limit(decay);
728730
/* We may unlock decay->mtx when try_purge(). Finish logging first. */
729731
decay->nunpurged = (npages_limit > current_npages) ? npages_limit :
730732
current_npages;
731-
if (purge) {
733+
734+
if (!background_thread_enabled() || is_background_thread) {
732735
arena_decay_try_purge(tsdn, arena, decay, extents,
733-
current_npages, npages_limit);
736+
current_npages, npages_limit, is_background_thread);
734737
}
735738
}
736739

@@ -795,7 +798,7 @@ arena_maybe_decay(tsdn_t *tsdn, arena_t *arena, arena_decay_t *decay,
795798
if (decay_ms <= 0) {
796799
if (decay_ms == 0) {
797800
arena_decay_to_limit(tsdn, arena, decay, extents, false,
798-
0);
801+
0, is_background_thread);
799802
}
800803
return false;
801804
}
@@ -830,14 +833,13 @@ arena_maybe_decay(tsdn_t *tsdn, arena_t *arena, arena_decay_t *decay,
830833
*/
831834
bool advance_epoch = arena_decay_deadline_reached(decay, &time);
832835
if (advance_epoch) {
833-
bool should_purge = is_background_thread ||
834-
!background_thread_enabled();
835836
arena_decay_epoch_advance(tsdn, arena, decay, extents, &time,
836-
should_purge);
837+
is_background_thread);
837838
} else if (is_background_thread) {
838839
arena_decay_try_purge(tsdn, arena, decay, extents,
839840
extents_npages_get(extents),
840-
arena_decay_backlog_npages_limit(decay));
841+
arena_decay_backlog_npages_limit(decay),
842+
is_background_thread);
841843
}
842844

843845
return advance_epoch;
@@ -916,7 +918,7 @@ arena_stash_decayed(tsdn_t *tsdn, arena_t *arena,
916918
static size_t
917919
arena_decay_stashed(tsdn_t *tsdn, arena_t *arena,
918920
extent_hooks_t **r_extent_hooks, arena_decay_t *decay, extents_t *extents,
919-
bool all, extent_list_t *decay_extents) {
921+
bool all, extent_list_t *decay_extents, bool is_background_thread) {
920922
UNUSED size_t nmadvise, nunmapped;
921923
size_t npurged;
922924

@@ -946,7 +948,7 @@ arena_decay_stashed(tsdn_t *tsdn, arena_t *arena,
946948
extents_dalloc(tsdn, arena, r_extent_hooks,
947949
&arena->extents_muzzy, extent);
948950
arena_background_thread_inactivity_check(tsdn,
949-
arena);
951+
arena, is_background_thread);
950952
break;
951953
}
952954
/* Fall through. */
@@ -985,7 +987,8 @@ arena_decay_stashed(tsdn_t *tsdn, arena_t *arena,
985987
*/
986988
static void
987989
arena_decay_to_limit(tsdn_t *tsdn, arena_t *arena, arena_decay_t *decay,
988-
extents_t *extents, bool all, size_t npages_limit) {
990+
extents_t *extents, bool all, size_t npages_limit,
991+
bool is_background_thread) {
989992
witness_assert_depth_to_rank(tsdn_witness_tsdp_get(tsdn),
990993
WITNESS_RANK_CORE, 1);
991994
malloc_mutex_assert_owner(tsdn, &decay->mtx);
@@ -1005,7 +1008,8 @@ arena_decay_to_limit(tsdn_t *tsdn, arena_t *arena, arena_decay_t *decay,
10051008
npages_limit, &decay_extents);
10061009
if (npurge != 0) {
10071010
UNUSED size_t npurged = arena_decay_stashed(tsdn, arena,
1008-
&extent_hooks, decay, extents, all, &decay_extents);
1011+
&extent_hooks, decay, extents, all, &decay_extents,
1012+
is_background_thread);
10091013
assert(npurged == npurge);
10101014
}
10111015

@@ -1018,7 +1022,8 @@ arena_decay_impl(tsdn_t *tsdn, arena_t *arena, arena_decay_t *decay,
10181022
extents_t *extents, bool is_background_thread, bool all) {
10191023
if (all) {
10201024
malloc_mutex_lock(tsdn, &decay->mtx);
1021-
arena_decay_to_limit(tsdn, arena, decay, extents, all, 0);
1025+
arena_decay_to_limit(tsdn, arena, decay, extents, all, 0,
1026+
is_background_thread);
10221027
malloc_mutex_unlock(tsdn, &decay->mtx);
10231028

10241029
return false;

0 commit comments

Comments
 (0)