mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 11:50:28 +02:00
Add gc_trace_worker_call_with_data
Goal is to pass thread-local evacuation buffers.
This commit is contained in:
parent
ac5d546481
commit
5ff78f01c8
4 changed files with 47 additions and 9 deletions
|
@ -32,6 +32,7 @@ struct trace_worker {
|
||||||
enum trace_worker_state state;
|
enum trace_worker_state state;
|
||||||
pthread_mutex_t lock;
|
pthread_mutex_t lock;
|
||||||
struct shared_worklist deque;
|
struct shared_worklist deque;
|
||||||
|
struct gc_trace_worker_data *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define TRACE_WORKERS_MAX_COUNT 8
|
#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->id = id;
|
||||||
worker->steal_id = 0;
|
worker->steal_id = 0;
|
||||||
worker->thread = 0;
|
worker->thread = 0;
|
||||||
|
worker->state = TRACE_WORKER_STOPPED;
|
||||||
pthread_mutex_init(&worker->lock, NULL);
|
pthread_mutex_init(&worker->lock, NULL);
|
||||||
|
worker->data = NULL;
|
||||||
return shared_worklist_init(&worker->deque);
|
return shared_worklist_init(&worker->deque);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,10 +275,13 @@ trace_worker_steal(struct local_tracer *trace) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
trace_worker_trace(struct trace_worker *worker) {
|
trace_with_data(struct gc_tracer *tracer,
|
||||||
struct gc_heap *heap = worker->heap;
|
struct gc_heap *heap,
|
||||||
struct gc_tracer *tracer = worker->tracer;
|
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);
|
atomic_fetch_add_explicit(&tracer->active_tracers, 1, memory_order_acq_rel);
|
||||||
|
worker->data = worker_data;
|
||||||
|
|
||||||
struct local_tracer trace;
|
struct local_tracer trace;
|
||||||
trace.worker = worker;
|
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);
|
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);
|
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
|
static inline void
|
||||||
gc_tracer_enqueue_root(struct gc_tracer *tracer, struct gc_ref ref) {
|
gc_tracer_enqueue_root(struct gc_tracer *tracer, struct gc_ref ref) {
|
||||||
struct shared_worklist *worker0_deque = &tracer->workers[0].deque;
|
struct shared_worklist *worker0_deque = &tracer->workers[0].deque;
|
||||||
|
|
|
@ -40,13 +40,20 @@ gc_tracer_enqueue(struct gc_tracer *tracer, struct gc_ref ref,
|
||||||
gc_tracer_enqueue_root(tracer, ref);
|
gc_tracer_enqueue_root(tracer, ref);
|
||||||
}
|
}
|
||||||
static inline void
|
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 {
|
do {
|
||||||
struct gc_ref obj = simple_worklist_pop(&tracer->worklist);
|
struct gc_ref obj = simple_worklist_pop(&tracer->worklist);
|
||||||
if (!gc_ref_is_heap_object(obj))
|
if (!gc_ref_is_heap_object(obj))
|
||||||
break;
|
break;
|
||||||
trace_one(obj, tracer->heap, NULL);
|
trace_one(obj, heap, NULL);
|
||||||
} while (1);
|
} 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
|
#endif // SERIAL_TRACER_H
|
||||||
|
|
15
src/tracer.h
15
src/tracer.h
|
@ -10,18 +10,25 @@ struct gc_heap;
|
||||||
/// To be implemented by collector.
|
/// To be implemented by collector.
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct gc_tracer;
|
||||||
|
struct gc_trace_worker_data;
|
||||||
// Visit all fields in an object.
|
// Visit all fields in an object.
|
||||||
static inline void trace_one(struct gc_ref ref, struct gc_heap *heap,
|
static inline void trace_one(struct gc_ref ref, struct gc_heap *heap,
|
||||||
void *trace_data) GC_ALWAYS_INLINE;
|
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.
|
/// 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.
|
// Initialize the tracer when the heap is created.
|
||||||
static int gc_tracer_init(struct gc_tracer *tracer, struct gc_heap *heap,
|
static int gc_tracer_init(struct gc_tracer *tracer, struct gc_heap *heap,
|
||||||
size_t parallelism);
|
size_t parallelism);
|
||||||
|
|
|
@ -1094,6 +1094,17 @@ void gc_heap_set_extern_space(struct gc_heap *heap,
|
||||||
heap->extern_space = space;
|
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,
|
static inline void tracer_visit(struct gc_edge edge, struct gc_heap *heap,
|
||||||
void *trace_data) GC_ALWAYS_INLINE;
|
void *trace_data) GC_ALWAYS_INLINE;
|
||||||
static inline void
|
static inline void
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue