wingo pushed a commit to branch wip-whippet
in repository guile.

commit 1e3122d054c584d4b1b6ca9cbea2dbe1e7651141
Author: Andy Wingo <wi...@igalia.com>
AuthorDate: Mon Oct 3 15:29:14 2022 +0200

    trace_worker_steal first does a try_pop on its own deque
    
    Before asking other threads for values, see if there is any pending data
    that overflowed from the local mark stack.
---
 parallel-tracer.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/parallel-tracer.h b/parallel-tracer.h
index a9600927b..bcc7910c2 100644
--- a/parallel-tracer.h
+++ b/parallel-tracer.h
@@ -547,6 +547,16 @@ trace_worker_steal(struct local_tracer *trace) {
   struct tracer *tracer = heap_tracer(trace->heap);
   struct trace_worker *worker = trace->worker;
 
+  // It could be that the worker's local trace queue has simply
+  // overflowed.  In that case avoid contention by trying to pop
+  // something from the worker's own queue.
+  {
+    DEBUG("tracer #%zu: trying to pop worker's own deque\n", worker->id);
+    struct gc_ref obj = trace_deque_try_pop(&worker->deque);
+    if (gc_ref_is_heap_object(obj))
+      return obj;
+  }
+
   while (1) {
     DEBUG("tracer #%zu: trying to steal\n", worker->id);
     struct gc_ref obj = trace_worker_steal_from_any(worker, tracer);

Reply via email to