Skip to content

Commit

Permalink
allow finalizers to take any locks and yield during exit (#51848)
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 authored Oct 25, 2023
1 parent 3493473 commit c54a3f2
Showing 1 changed file with 5 additions and 5 deletions.
10 changes: 5 additions & 5 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 finalizers_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 @@ -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 c54a3f2

Please sign in to comment.