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

commit 5ff78f01c88e77c73bb17f36ad85ea2b75c4f218
Author: Andy Wingo <wi...@igalia.com>
AuthorDate: Mon Jul 8 18:09:34 2024 +0200

    Add gc_trace_worker_call_with_data
    
    Goal is to pass thread-local evacuation buffers.
---
 src/parallel-tracer.h | 19 ++++++++++++++++---
 src/serial-tracer.h   | 11 +++++++++--
 src/tracer.h          | 15 +++++++++++----
 src/whippet.c         | 11 +++++++++++
 4 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/src/parallel-tracer.h b/src/parallel-tracer.h
index 6b25ea1a8..4bfa0490f 100644
--- a/src/parallel-tracer.h
+++ b/src/parallel-tracer.h
@@ -32,6 +32,7 @@ struct trace_worker {
   enum trace_worker_state state;
   pthread_mutex_t lock;
   struct shared_worklist deque;
+  struct gc_trace_worker_data *data;
 };
 
 #define TRACE_WORKERS_MAX_COUNT 8
@@ -60,7 +61,9 @@ trace_worker_init(struct trace_worker *worker, struct gc_heap 
*heap,
   worker->id = id;
   worker->steal_id = 0;
   worker->thread = 0;
+  worker->state = TRACE_WORKER_STOPPED;
   pthread_mutex_init(&worker->lock, NULL);
+  worker->data = NULL;
   return shared_worklist_init(&worker->deque);
 }
 
@@ -272,10 +275,13 @@ trace_worker_steal(struct local_tracer *trace) {
 }
 
 static void
-trace_worker_trace(struct trace_worker *worker) {
-  struct gc_heap *heap = worker->heap;
-  struct gc_tracer *tracer = worker->tracer;
+trace_with_data(struct gc_tracer *tracer,
+                struct gc_heap *heap,
+                struct gc_trace_worker_data *worker_data,
+                void *data) {
+  struct trace_worker *worker = data;
   atomic_fetch_add_explicit(&tracer->active_tracers, 1, memory_order_acq_rel);
+  worker->data = worker_data;
 
   struct local_tracer trace;
   trace.worker = worker;
@@ -302,9 +308,16 @@ trace_worker_trace(struct trace_worker *worker) {
 
   DEBUG("tracer #%zu: done tracing, %zu objects traced\n", worker->id, n);
 
+  worker->data = NULL;
   atomic_fetch_sub_explicit(&tracer->active_tracers, 1, memory_order_acq_rel);
 }
 
+static void
+trace_worker_trace(struct trace_worker *worker) {
+  gc_trace_worker_call_with_data(trace_with_data, worker->tracer,
+                                 worker->heap, worker);
+}
+
 static inline void
 gc_tracer_enqueue_root(struct gc_tracer *tracer, struct gc_ref ref) {
   struct shared_worklist *worker0_deque = &tracer->workers[0].deque;
diff --git a/src/serial-tracer.h b/src/serial-tracer.h
index fffa133dd..c75425bde 100644
--- a/src/serial-tracer.h
+++ b/src/serial-tracer.h
@@ -40,13 +40,20 @@ gc_tracer_enqueue(struct gc_tracer *tracer, struct gc_ref 
ref,
   gc_tracer_enqueue_root(tracer, ref);
 }
 static inline void
-gc_tracer_trace(struct gc_tracer *tracer) {
+tracer_trace_with_data(struct gc_tracer *tracer, struct gc_heap *heap,
+                       struct gc_trace_worker_data *worker_data,
+                       void *data) {
   do {
     struct gc_ref obj = simple_worklist_pop(&tracer->worklist);
     if (!gc_ref_is_heap_object(obj))
       break;
-    trace_one(obj, tracer->heap, NULL);
+    trace_one(obj, heap, NULL);
   } while (1);
 }
+static inline void
+gc_tracer_trace(struct gc_tracer *tracer) {
+  gc_trace_worker_call_with_data(tracer_trace_with_data, tracer, tracer->heap,
+                                 NULL);
+}
 
 #endif // SERIAL_TRACER_H
diff --git a/src/tracer.h b/src/tracer.h
index 0208f6aa8..f0524406a 100644
--- a/src/tracer.h
+++ b/src/tracer.h
@@ -10,18 +10,25 @@ struct gc_heap;
 /// To be implemented by collector.
 ////////////////////////////////////////////////////////////////////////
 
+struct gc_tracer;
+struct gc_trace_worker_data;
 // Visit all fields in an object.
 static inline void trace_one(struct gc_ref ref, struct gc_heap *heap,
                              void *trace_data) GC_ALWAYS_INLINE;
 
+static void
+gc_trace_worker_call_with_data(void (*f)(struct gc_tracer *tracer,
+                                         struct gc_heap *heap,
+                                         struct gc_trace_worker_data 
*worker_data,
+                                         void *data),
+                               struct gc_tracer *tracer,
+                               struct gc_heap *heap,
+                               void *data);
+
 ////////////////////////////////////////////////////////////////////////
 /// To be implemented by tracer.
 ////////////////////////////////////////////////////////////////////////
 
-// The tracer struct itself should be defined by the tracer
-// implementation.
-struct gc_tracer;
-
 // Initialize the tracer when the heap is created.
 static int gc_tracer_init(struct gc_tracer *tracer, struct gc_heap *heap,
                           size_t parallelism);
diff --git a/src/whippet.c b/src/whippet.c
index d56476ffc..63dd1775e 100644
--- a/src/whippet.c
+++ b/src/whippet.c
@@ -1094,6 +1094,17 @@ void gc_heap_set_extern_space(struct gc_heap *heap,
   heap->extern_space = space;
 }
 
+static void
+gc_trace_worker_call_with_data(void (*f)(struct gc_tracer *tracer,
+                                         struct gc_heap *heap,
+                                         struct gc_trace_worker_data 
*worker_data,
+                                         void *data),
+                               struct gc_tracer *tracer,
+                               struct gc_heap *heap,
+                               void *data) {
+  f(tracer, heap, NULL, data);
+}
+
 static inline void tracer_visit(struct gc_edge edge, struct gc_heap *heap,
                                 void *trace_data) GC_ALWAYS_INLINE;
 static inline void

Reply via email to