summaryrefslogtreecommitdiff
path: root/libguile/whippet/src/pcc.c
diff options
context:
space:
mode:
Diffstat (limited to 'libguile/whippet/src/pcc.c')
-rw-r--r--libguile/whippet/src/pcc.c44
1 files changed, 39 insertions, 5 deletions
diff --git a/libguile/whippet/src/pcc.c b/libguile/whippet/src/pcc.c
index 6b656360c..c0aef49fd 100644
--- a/libguile/whippet/src/pcc.c
+++ b/libguile/whippet/src/pcc.c
@@ -96,6 +96,7 @@ struct gc_mutator {
void *event_listener_data;
struct gc_mutator *next;
struct gc_mutator *prev;
+ int active;
};
struct gc_trace_worker_data {
@@ -501,6 +502,7 @@ static void add_mutator(struct gc_heap *heap, struct gc_mutator *mut) {
while (mutators_are_stopping(heap))
pthread_cond_wait(&heap->mutator_cond, &heap->lock);
mut->next = mut->prev = NULL;
+ mut->active = 1;
struct gc_mutator *tail = heap->mutators;
if (tail) {
mut->next = tail;
@@ -520,6 +522,7 @@ static void remove_mutator(struct gc_heap *heap, struct gc_mutator *mut) {
mut->heap = NULL;
heap_lock(heap);
heap->mutator_count--;
+ mut->active = 0;
if (mut->next)
mut->next->prev = mut->prev;
if (mut->prev)
@@ -902,11 +905,11 @@ collect(struct gc_mutator *mut, enum gc_collection_kind requested_kind) {
heap->is_minor_collection =
#endif
GC_GENERATIONAL ? gc_kind == GC_COLLECTION_MINOR : 0;
- HEAP_EVENT(heap, prepare_gc, gc_kind);
uint64_t *counter_loc = &heap->total_allocated_bytes_at_last_gc;
copy_space_add_to_allocation_counter(heap_allocation_space(heap),
counter_loc);
large_object_space_add_to_allocation_counter(lospace, counter_loc);
+ HEAP_EVENT(heap, prepare_gc, gc_kind, *counter_loc);
copy_spaces_start_gc(heap, is_minor_gc);
large_object_space_start_gc(lospace, is_minor_gc);
gc_extern_space_start_gc(exspace, is_minor_gc);
@@ -1081,6 +1084,10 @@ void gc_safepoint_slow(struct gc_mutator *mut) {
heap_unlock(heap);
}
+int gc_safepoint_signal_number(void) { GC_CRASH(); }
+void gc_safepoint_signal_inhibit(struct gc_mutator *mut) { GC_CRASH(); }
+void gc_safepoint_signal_reallow(struct gc_mutator *mut) { GC_CRASH(); }
+
struct gc_ephemeron* gc_allocate_ephemeron(struct gc_mutator *mut) {
return gc_allocate(mut, gc_ephemeron_size(), GC_ALLOCATION_TAGGED);
}
@@ -1354,31 +1361,58 @@ void gc_finish_for_thread(struct gc_mutator *mut) {
static void deactivate_mutator(struct gc_heap *heap, struct gc_mutator *mut) {
GC_ASSERT(mut->next == NULL);
+ GC_ASSERT(mut->active);
copy_space_allocator_finish(&mut->allocator, heap_allocation_space(heap));
if (GC_GENERATIONAL)
gc_field_set_writer_release_buffer(mutator_field_logger(mut));
heap_lock(heap);
heap->inactive_mutator_count++;
+ mut->active = 0;
if (all_mutators_stopped(heap))
pthread_cond_signal(&heap->collector_cond);
heap_unlock(heap);
}
static void reactivate_mutator(struct gc_heap *heap, struct gc_mutator *mut) {
+ GC_ASSERT(!mut->active);
heap_lock(heap);
while (mutators_are_stopping(heap))
pthread_cond_wait(&heap->mutator_cond, &heap->lock);
+ mut->active = 1;
heap->inactive_mutator_count--;
maybe_increase_max_active_mutator_count(heap);
heap_unlock(heap);
}
-void* gc_call_without_gc(struct gc_mutator *mut,
- void* (*f)(void*),
- void *data) {
+void gc_deactivate(struct gc_mutator *mut) {
+ GC_ASSERT(mut->active);
+ deactivate_mutator(mutator_heap(mut), mut);
+}
+
+void gc_reactivate(struct gc_mutator *mut) {
+ GC_ASSERT(!mut->active);
+ reactivate_mutator(mutator_heap(mut), mut);
+}
+
+void* gc_deactivate_for_call(struct gc_mutator *mut,
+ void* (*f)(struct gc_mutator*, void*),
+ void *data) {
struct gc_heap *heap = mutator_heap(mut);
deactivate_mutator(heap, mut);
- void *ret = f(data);
+ void *ret = f(mut, data);
reactivate_mutator(heap, mut);
return ret;
}
+
+void* gc_reactivate_for_call(struct gc_mutator *mut,
+ void* (*f)(struct gc_mutator*, void*),
+ void *data) {
+ struct gc_heap *heap = mutator_heap(mut);
+ int reactivate = !mut->active;
+ if (reactivate)
+ reactivate_mutator(heap, mut);
+ void *ret = f(mut, data);
+ if (reactivate)
+ deactivate_mutator(heap, mut);
+ return ret;
+}