From 1bd2f6a650a041ec5cb2c3eaa8549813bf0416b7 Mon Sep 17 00:00:00 2001 From: Tim Besard Date: Tue, 23 May 2023 14:14:29 +0200 Subject: [PATCH] Disable GC during thread adoption. Otherwise GC might run after the foreign thread exits the spin loop, but before it is initialized and ready to handle GC safepoints. --- src/gc.c | 2 +- src/julia_internal.h | 1 + src/threading.c | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gc.c b/src/gc.c index 846ade33b271a8..528d4dc8a03041 100644 --- a/src/gc.c +++ b/src/gc.c @@ -3068,7 +3068,7 @@ static void sweep_finalizer_list(arraylist_t *list) } // collector entry point and control -static _Atomic(uint32_t) jl_gc_disable_counter = 1; +_Atomic(uint32_t) jl_gc_disable_counter = 1; JL_DLLEXPORT int jl_gc_enable(int on) { diff --git a/src/julia_internal.h b/src/julia_internal.h index a43458f4c5a6ef..71482bd2ef47d4 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -883,6 +883,7 @@ STATIC_INLINE int jl_addr_is_safepoint(uintptr_t addr) return addr >= safepoint_addr && addr < safepoint_addr + jl_page_size * 3; } extern _Atomic(uint32_t) jl_gc_running; +extern _Atomic(uint32_t) jl_gc_disable_counter; // All the functions are safe to be called from within a signal handler // provided that the thread will not be interrupted by another asynchronous // signal. diff --git a/src/threading.c b/src/threading.c index e5271fb9f823a6..e901d0c77c877f 100644 --- a/src/threading.c +++ b/src/threading.c @@ -414,6 +414,7 @@ JL_DLLEXPORT jl_gcframe_t **jl_adopt_thread(void) JL_NOTSAFEPOINT_LEAVE while (jl_atomic_load_relaxed(&jl_gc_running) || jl_atomic_load_acquire(&jl_gc_running)) { jl_cpu_pause(); } + jl_atomic_fetch_add(&jl_gc_disable_counter, 1); // initialize this thread (assign tid, create heap, set up root task) jl_ptls_t ptls = jl_init_threadtls(-1); @@ -424,6 +425,7 @@ JL_DLLEXPORT jl_gcframe_t **jl_adopt_thread(void) JL_NOTSAFEPOINT_LEAVE jl_task_t *ct = jl_init_root_task(ptls, stack_lo, stack_hi); JL_GC_PROMISE_ROOTED(ct); uv_random(NULL, NULL, &ct->rngState, sizeof(ct->rngState), 0, NULL); + jl_atomic_fetch_add(&jl_gc_disable_counter, -1); return &ct->gcstack; }