wingo pushed a commit to branch wip-whippet in repository guile. commit 5375c03c759c4100074ad3305de813344326429a Author: Andy Wingo <wi...@igalia.com> AuthorDate: Mon Jul 7 16:38:19 2025 +0200
parallel tracer: An amazing bug-fix! Previously, tracing roots would enqueue refs in local worklists. If we had to separate root and main tracing, for example because of pinned ambiguous stack roots, then perhaps those worker threads would not get woken up during the main trace, leading to references being lost. --- src/parallel-tracer.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/parallel-tracer.h b/src/parallel-tracer.h index db8afae8a..70edbe7f2 100644 --- a/src/parallel-tracer.h +++ b/src/parallel-tracer.h @@ -184,6 +184,19 @@ tracer_share(struct gc_trace_worker *worker) { tracer_maybe_unpark_workers(worker->tracer); } +static inline void +tracer_share_all(struct gc_trace_worker *worker) { + LOG("tracer #%zu: found %zu roots\n", worker->id, + local_worklist_size (&worker->local)); + while (!local_worklist_empty (&worker->local)) { + struct gc_ref *objv; + size_t count = + local_worklist_pop_many(&worker->local, &objv, LOCAL_WORKLIST_SIZE); + shared_worklist_push_many(&worker->shared, objv, count); + } + // No unparking; this is used at the end of a roots-only trace. +} + static inline void gc_trace_worker_enqueue(struct gc_trace_worker *worker, struct gc_ref ref) { ASSERT(gc_ref_is_heap_object(ref)); @@ -332,6 +345,7 @@ trace_with_data(struct gc_tracer *tracer, // result of marking roots isn't ours to deal with. However we do need to // synchronize with remote workers to ensure they have completed their // work items. + tracer_share_all(worker); if (worker->id == 0) { for (size_t i = 1; i < tracer->worker_count; i++) pthread_mutex_lock(&tracer->workers[i].lock);