Skip to content

Commit

Permalink
allow finalizers to take any locks and yield during exit
Browse files Browse the repository at this point in the history
This aligns their behavior with manual calls to `finalize(o)`, and
prepares for a future time in which these functions are always run on a
separate thread. This means that they can wait to acquire locks in this
context, which otherwise would have been denied to them.
  • Loading branch information
vtjnash committed Oct 24, 2023
1 parent 2d8325b commit 79e9abb
Showing 1 changed file with 6 additions and 6 deletions.
12 changes: 6 additions & 6 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ JL_DLLEXPORT void jl_gc_init_finalizer_rng_state(void)
jl_rng_split(finalizer_rngState, jl_current_task->rngState);
}

static void run_finalizers(jl_task_t *ct)
static void run_finalizers(jl_task_t *ct, int finalizer_thread)
{
// Racy fast path:
// The race here should be OK since the race can only happen if
Expand Down Expand Up @@ -453,7 +453,7 @@ static void run_finalizers(jl_task_t *ct)

// This releases the finalizers lock.
int8_t was_in_finalizer = ct->ptls->in_finalizer;
ct->ptls->in_finalizer = 1;
ct->ptls->in_finalizer = !finalizers_thread;
jl_gc_run_finalizers_in_list(ct, &copied_list);
ct->ptls->in_finalizer = was_in_finalizer;
arraylist_free(&copied_list);
Expand All @@ -467,7 +467,7 @@ JL_DLLEXPORT void jl_gc_run_pending_finalizers(jl_task_t *ct)
ct = jl_current_task;
jl_ptls_t ptls = ct->ptls;
if (!ptls->in_finalizer && ptls->locks.len == 0 && ptls->finalizers_inhibited == 0) {
run_finalizers(ct);
run_finalizers(ct, 0);
}
}

Expand Down Expand Up @@ -560,7 +560,7 @@ void jl_gc_run_all_finalizers(jl_task_t *ct)
JL_UNLOCK_NOGC(&finalizers_lock);
gc_n_threads = 0;
gc_all_tls_states = NULL;
run_finalizers(ct);
run_finalizers(ct, 1);
}

void jl_gc_add_finalizer_(jl_ptls_t ptls, void *v, void *f) JL_NOTSAFEPOINT
Expand Down Expand Up @@ -637,7 +637,7 @@ JL_DLLEXPORT void jl_finalize_th(jl_task_t *ct, jl_value_t *o)
gc_all_tls_states = NULL;
if (copied_list.len > 0) {
// This releases the finalizers lock.
jl_gc_run_finalizers_in_list(ct, &copied_list);
jl_gc_run_finalizers_in_list(ct, &copied_list, 0);
}
else {
JL_UNLOCK_NOGC(&finalizers_lock);
Expand Down Expand Up @@ -3588,7 +3588,7 @@ JL_DLLEXPORT void jl_gc_collect(jl_gc_collection_t collection)
// or wait for finalizers on other threads without dead lock).
if (!ptls->finalizers_inhibited && ptls->locks.len == 0) {
JL_TIMING(GC, GC_Finalizers);
run_finalizers(ct);
run_finalizers(ct, 0);
}
JL_PROBE_GC_FINALIZER();

Expand Down

0 comments on commit 79e9abb

Please sign in to comment.