From 5ff78f01c88e77c73bb17f36ad85ea2b75c4f218 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Mon, 8 Jul 2024 18:09:34 +0200 Subject: [PATCH] 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