From 78a817d84402583e7f492fd1ad0e785829ad53fb Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Sat, 9 Sep 2023 18:13:49 -0400 Subject: [PATCH] Handle gcanalyzer --- src/jl_uv.c | 13 ++++++++----- src/julia_internal.h | 4 ++-- src/threading.c | 16 +++++++++------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/jl_uv.c b/src/jl_uv.c index 5712a9fedb3b6..8d5414a2c6890 100644 --- a/src/jl_uv.c +++ b/src/jl_uv.c @@ -56,7 +56,7 @@ static void jl_uv_cb_walk_print(uv_handle_t *h, void *arg) jl_safe_printf(" %s[%zd] %s@%p->%p\n", type, (size_t)fd, pad, (void*)h, (void*)h->data); } -static void jl_uv_cb_wait_empty(uv_timer_t *t) +static void jl_uv_cb_wait_empty(uv_timer_t *t) JL_NOTSAFEPOINT_ENTER { // make sure this is hidden now, since we would auto-unref it later uv_unref((uv_handle_t*)&signal_async); @@ -69,7 +69,7 @@ static void jl_uv_cb_wait_empty(uv_timer_t *t) jl_ptls_t ptls = jl_current_task->ptls; int old_state = jl_gc_unsafe_enter(ptls); jl_gc_collect(JL_GC_FULL); - jl_gc_unsafe_leave(ptls,old_state); + jl_gc_unsafe_leave(ptls, old_state); } void jl_wait_empty_begin(void) @@ -154,7 +154,7 @@ JL_DLLEXPORT void jl_iolock_end(void) } -static void jl_uv_call_hook_close(jl_value_t *val) +static void jl_uv_call_hook_close(jl_value_t *val) JL_NOTSAFEPOINT_ENTER { jl_ptls_t ptls = jl_current_task->ptls; int old_state = jl_gc_unsafe_enter(ptls); @@ -166,7 +166,7 @@ static void jl_uv_call_hook_close(jl_value_t *val) assert(args[0]); jl_apply(args, 2); // TODO: wrap in try-catch? JL_GC_POP(); - jl_gc_unsafe_leave(ptls,old_state); + jl_gc_unsafe_leave(ptls, old_state); } static void jl_uv_cb_close_handle(uv_handle_t *handle) @@ -282,7 +282,10 @@ JL_DLLEXPORT void *jl_uv_handle_data(uv_handle_t *handle) { return handle->data; JL_DLLEXPORT void *jl_uv_write_handle(uv_write_t *req) { return req->handle; } -int jl_process_events_locked(void) { +// This is JL_NOTSAFEPOINT, but the analyzer complains about uv_run. +// Callabacks need to handle their GC transitions themselves. +int jl_process_events_locked(void) // JL_NOTSAFEPOINT +{ uv_loop_t *loop = jl_io_loop; loop->stop_flag = 0; uv_ref((uv_handle_t*)&signal_async); // force the loop alive diff --git a/src/julia_internal.h b/src/julia_internal.h index 0f6ad5d01b097..a47d55e234cf7 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -181,8 +181,8 @@ static uv_loop_t *const unused_uv_loop_arg = (uv_loop_t *)0xBAD10; extern jl_mutex_t jl_uv_mutex; extern _Atomic(int) jl_uv_n_waiters; void JL_UV_LOCK(void); -int JL_UV_TRYLOCK_NOGC(void); -void JL_UV_UNLOCK_NOGC(void); +int JL_UV_TRYLOCK_NOGC(void) JL_NOTSAFEPOINT; +void JL_UV_UNLOCK_NOGC(void) JL_NOTSAFEPOINT; #define JL_UV_UNLOCK() JL_UNLOCK(&jl_uv_mutex) #ifdef __cplusplus diff --git a/src/threading.c b/src/threading.c index 1239696bdac6a..12df923e790a8 100644 --- a/src/threading.c +++ b/src/threading.c @@ -702,21 +702,22 @@ void jl_init_threading(void) gc_first_tid = nthreads; } -int jl_process_events_locked(void); -void jl_utility_io_threadfun(void *arg) { - +int jl_process_events_locked(void) JL_NOTSAFEPOINT; +void jl_utility_io_threadfun(void *arg) +{ jl_adopt_thread(); jl_ptls_t ptls = jl_current_task->ptls; - jl_gc_safe_enter(ptls); + int8_t gc_state = jl_gc_safe_enter(ptls); while (1) { - // Only reader of the rwlock, according to libuv lock is writer-biased if (jl_atomic_load_relaxed(&jl_uv_n_waiters) == 0) if (JL_UV_TRYLOCK_NOGC()) { jl_process_events_locked(); JL_UV_UNLOCK_NOGC(); } + // TODO: jl_fence(); // [^store_buffering_2] } + jl_gc_safe_leave(ptls, gc_state); return; } @@ -781,10 +782,11 @@ void jl_start_threads(void) } uv_thread_detach(&uvtid); } + uv_barrier_wait(&thread_init_done); + + // utility thread uses jl_adopt_thread uv_thread_create(&uvtid, jl_utility_io_threadfun, NULL); uv_thread_detach(&uvtid); - - uv_barrier_wait(&thread_init_done); } // Profiling stubs