1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-09 13:30:26 +02:00

Implement cooperative safepoint API

Fixes https://github.com/wingo/whippet/issues/9.
This commit is contained in:
Andy Wingo 2024-09-18 11:31:06 +02:00
parent 9f26dbb1fc
commit 8fba0e5322
11 changed files with 95 additions and 63 deletions

View file

@ -417,6 +417,7 @@ static enum gc_collection_kind
pause_mutator_for_collection(struct gc_heap *heap, struct gc_mutator *mut) {
GC_ASSERT(mutators_are_stopping(heap));
GC_ASSERT(!all_mutators_stopped(heap));
MUTATOR_EVENT(mut, mutator_stopping);
MUTATOR_EVENT(mut, mutator_stopped);
heap->paused_mutator_count++;
enum gc_collection_kind collection_kind = heap->gc_kind;
@ -432,35 +433,6 @@ pause_mutator_for_collection(struct gc_heap *heap, struct gc_mutator *mut) {
return collection_kind;
}
static enum gc_collection_kind
pause_mutator_for_collection_with_lock(struct gc_mutator *mut) GC_NEVER_INLINE;
static enum gc_collection_kind
pause_mutator_for_collection_with_lock(struct gc_mutator *mut) {
struct gc_heap *heap = mutator_heap(mut);
GC_ASSERT(mutators_are_stopping(heap));
MUTATOR_EVENT(mut, mutator_stopping);
return pause_mutator_for_collection(heap, mut);
}
static void pause_mutator_for_collection_without_lock(struct gc_mutator *mut) GC_NEVER_INLINE;
static void
pause_mutator_for_collection_without_lock(struct gc_mutator *mut) {
struct gc_heap *heap = mutator_heap(mut);
GC_ASSERT(mutators_are_stopping(heap));
MUTATOR_EVENT(mut, mutator_stopping);
nofl_finish_sweeping(&mut->allocator, heap_nofl_space(heap));
gc_stack_capture_hot(&mut->stack);
heap_lock(heap);
pause_mutator_for_collection(heap, mut);
heap_unlock(heap);
}
static inline void
maybe_pause_mutator_for_collection(struct gc_mutator *mut) {
while (mutators_are_stopping(mutator_heap(mut)))
pause_mutator_for_collection_without_lock(mut);
}
static void
resize_heap(struct gc_heap *heap, size_t new_size) {
if (new_size == heap->size)
@ -818,7 +790,7 @@ trigger_collection(struct gc_mutator *mut,
nofl_allocator_finish(&mut->allocator, heap_nofl_space(heap));
heap_lock(heap);
while (mutators_are_stopping(heap))
prev_kind = pause_mutator_for_collection_with_lock(mut);
prev_kind = pause_mutator_for_collection(heap, mut);
if (prev_kind < (int)requested_kind)
collect(mut, requested_kind);
heap_unlock(heap);
@ -829,6 +801,22 @@ gc_collect(struct gc_mutator *mut, enum gc_collection_kind kind) {
trigger_collection(mut, kind);
}
int*
gc_safepoint_flag_loc(struct gc_mutator *mut) {
return &mutator_heap(mut)->collecting;
}
void
gc_safepoint_slow(struct gc_mutator *mut) {
struct gc_heap *heap = mutator_heap(mut);
gc_stack_capture_hot(&mut->stack);
nofl_allocator_finish(&mut->allocator, heap_nofl_space(heap));
heap_lock(heap);
while (mutators_are_stopping(mutator_heap(mut)))
pause_mutator_for_collection(heap, mut);
heap_unlock(heap);
}
static void*
allocate_large(struct gc_mutator *mut, size_t size) {
struct gc_heap *heap = mutator_heap(mut);
@ -894,7 +882,7 @@ gc_write_barrier_extern(struct gc_ref obj, size_t obj_size,
GC_ASSERT(obj_size > gc_allocator_large_threshold());
gc_object_set_remembered(obj);
}
struct gc_ephemeron*
gc_allocate_ephemeron(struct gc_mutator *mut) {
struct gc_ref ret =