Skip to content

Commit

Permalink
Revert to using old GC_finalize mechanism
Browse files Browse the repository at this point in the history
Using an extension of the disclaim API proved difficult because of the
need to re-mark objects pointed to by finalisable objects before a
finaliser is run. This would have led to complex changes to the
mark-phase for no real benefit.

Instead, by switching back to the GC_finalize mechanism but ensuring
that finalisers are run off of mutator threads, we get this desired
behaviour 'for free'.

This approach uses a simple condition variable to sleep the finaliser thread
when there is no finalisation work to do. This is then potentially
resumed at the end of a GC cycle if that cycle discovered finalisable
objects.
  • Loading branch information
jacob-hughes committed Aug 21, 2024
1 parent 773862b commit e093be9
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 5 deletions.
10 changes: 5 additions & 5 deletions include/private/gc_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ typedef struct hblkhdr hdr;

#include "gc/gc_inline.h"

<<<<<<< HEAD
#ifdef BUFFERED_FINALIZATION

typedef struct GC_finalization_buffer_hdr GC_finalization_buffer_hdr;
Expand All @@ -355,6 +356,9 @@ struct GC_current_buffer {
};

GC_INNER void GC_maybe_spawn_finalize_thread();
=======
GC_INNER void GC_maybe_wake_finalizer_thread();
>>>>>>> b44b0a3e (Revert to using old GC_finalize mechanism)

#endif

Expand Down Expand Up @@ -402,11 +406,7 @@ GC_INNER void GC_maybe_spawn_finalize_thread();
EXTERN_C_BEGIN

#ifndef GC_NO_FINALIZATION
#ifdef BUFFERED_FINALIZATION
# define GC_INVOKE_FINALIZERS() GC_maybe_spawn_finalize_thread()
#else
# define GC_INVOKE_FINALIZERS() GC_notify_or_invoke_finalizers()
#endif
# define GC_INVOKE_FINALIZERS() GC_maybe_wake_finalizer_thread()
GC_INNER void GC_notify_or_invoke_finalizers(void);
/* If GC_finalize_on_demand is not set, invoke */
/* eligible finalizers. Otherwise: */
Expand Down
37 changes: 37 additions & 0 deletions reclaim.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@
# include "gc/gc_disclaim.h"
#endif

#ifdef GC_PTHREADS
static pthread_mutex_t flzr_mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t flzr_t_has_work = PTHREAD_COND_INITIALIZER;
#elif
#error "This fork of BDWGC only supports POSIX threads"
#endif

GC_INNER signed_word GC_bytes_found = 0;
/* Number of bytes of memory reclaimed */
/* minus the number of bytes originally */
Expand Down Expand Up @@ -876,3 +883,33 @@ GC_API void GC_CALL GC_enumerate_reachable_objects_inner(
ed.client_data = client_data;
GC_apply_to_all_blocks(GC_do_enumerate_reachable_objects, (word)&ed);
}

static void* init_finalize_thread(void *arg)
{
while(1) {
pthread_mutex_lock(&flzr_mtx);
while (GC_should_invoke_finalizers() == 0) {
pthread_cond_wait(&flzr_t_has_work, &flzr_mtx);
}
pthread_mutex_unlock(&flzr_mtx);
GC_invoke_finalizers();
}
return arg;
}

GC_INNER void GC_maybe_wake_finalizer_thread()
{
if (!GC_finalizer_thread_exists) {
pthread_t t;
pthread_create(&t, NULL, init_finalize_thread, NULL /* arg */);
GC_finalizer_thread_exists = 1;
return;
}

if (GC_should_invoke_finalizers() == 0)
return;

pthread_mutex_lock(&flzr_mtx);
pthread_cond_signal(&flzr_t_has_work);
pthread_mutex_unlock(&flzr_mtx);
}

0 comments on commit e093be9

Please sign in to comment.