diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 893c6372b..74aa27825 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -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; @@ -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 @@ -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: */ diff --git a/reclaim.c b/reclaim.c index ae6a420c9..9675fa199 100644 --- a/reclaim.c +++ b/reclaim.c @@ -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 */ @@ -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); +}