Skip to content

Commit

Permalink
Merge pull request #17 from jacob-hughes/lazy_finalization
Browse files Browse the repository at this point in the history
Lazily spawn finalisation thread
  • Loading branch information
ltratt authored Apr 17, 2024
2 parents a601f2a + fd7ce82 commit 9bfdaa2
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 29 deletions.
41 changes: 23 additions & 18 deletions fnlz_mlc.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,6 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_finalized_malloc(size_t lb,

# ifdef BUFFERED_FINALIZATION

STATIC GC_finalization_buffer_hdr* start_buffer;
STATIC struct GC_current_buffer cur_buffer;

static void* init_finalize_thread(void *arg)
{
while (1) {
Expand Down Expand Up @@ -176,28 +173,28 @@ STATIC int GC_CALLBACK GC_push_object_to_fin_buffer(void *obj)
return 0;
}

if (start_buffer == NULL) {
if (GC_finalizer_buffer_head == NULL) {
/* This can happen for two reasons:
* 1) This is first time a finalizable object is unreachable and no
* finalization buffers have been created yet.
*
* 2) The buffer(s) have already passed to a finalization thread
* which is processing them. We must start again. */
start_buffer = GC_new_buffer();
cur_buffer.hdr = start_buffer;
cur_buffer.cursor = (void**) (start_buffer + 1);
GC_finalizer_buffer_head = GC_new_buffer();
GC_finalizer_buffer_current.hdr = GC_finalizer_buffer_head;
GC_finalizer_buffer_current.cursor = (void**) (GC_finalizer_buffer_head + 1);
}

void** last = (void**) ((void *)cur_buffer.hdr + GC_page_size);
if (cur_buffer.cursor == last) {
void** last = (void**) ((void *)GC_finalizer_buffer_current.hdr + GC_page_size);
if (GC_finalizer_buffer_current.cursor == last) {
GC_finalization_buffer_hdr* next = GC_new_buffer();
cur_buffer.hdr->next = next;
cur_buffer.hdr = next;
cur_buffer.cursor = (void**) (next + 1);
GC_finalizer_buffer_current.hdr->next = next;
GC_finalizer_buffer_current.hdr = next;
GC_finalizer_buffer_current.cursor = (void**) (next + 1);
}

*cur_buffer.cursor = obj;
cur_buffer.cursor++;
*GC_finalizer_buffer_current.cursor = obj;
GC_finalizer_buffer_current.cursor++;

return 1;
}
Expand Down Expand Up @@ -225,8 +222,6 @@ GC_API void GC_CALL GC_init_buffered_finalization(void)

GC_register_disclaim_proc_inner(GC_fin_q_kind, GC_push_object_to_fin_buffer, TRUE);
UNLOCK();
pthread_t t;
pthread_create(&t, NULL, init_finalize_thread, NULL /* arg */);
}

void GC_finalize_buffer(GC_finalization_buffer_hdr* buffer) {
Expand Down Expand Up @@ -256,8 +251,8 @@ GC_API void GC_CALL GC_finalize_objects(void) {
* collection, so the finalisation thread will always load the up-to-date
* version of this global. */
GC_disable();
GC_finalization_buffer_hdr* buffer = start_buffer;
start_buffer = NULL;
GC_finalization_buffer_hdr* buffer = GC_finalizer_buffer_head;
GC_finalizer_buffer_head = NULL;
GC_enable();

while(buffer != NULL)
Expand All @@ -270,6 +265,16 @@ GC_API void GC_CALL GC_finalize_objects(void) {
}
}

GC_INNER void GC_maybe_spawn_finalize_thread()
{
if (GC_finalizer_thread_exists || !GC_finalizer_buffer_head)
return;

pthread_t t;
pthread_create(&t, NULL, init_finalize_thread, NULL /* arg */);
GC_finalizer_thread_exists = 1;
}

# endif

#endif /* ENABLE_DISCLAIM */
11 changes: 0 additions & 11 deletions include/gc/gc_disclaim.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,6 @@ GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL
const struct GC_finalizer_closure * /* fc */) GC_ATTR_NONNULL(2);


typedef struct GC_finalization_buffer_hdr GC_finalization_buffer_hdr;

struct GC_finalization_buffer_hdr {
GC_finalization_buffer_hdr* next;
};

struct GC_current_buffer {
GC_finalization_buffer_hdr* hdr;
void** cursor;
};

/* This API is defined only if the library has been suitably compiled */
/* (i.e. with ENABLE_DISCLAIM defined). */

Expand Down
29 changes: 29 additions & 0 deletions include/private/gc_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,23 @@ typedef unsigned int unsigned32;

#include "gc/gc_inline.h"

#ifdef BUFFERED_FINALIZATION

typedef struct GC_finalization_buffer_hdr GC_finalization_buffer_hdr;

struct GC_finalization_buffer_hdr {
GC_finalization_buffer_hdr* next;
};

struct GC_current_buffer {
GC_finalization_buffer_hdr* hdr;
void** cursor;
};

GC_INNER void GC_maybe_spawn_finalize_thread();

#endif

/*********************************/
/* */
/* Definitions for conservative */
Expand Down Expand Up @@ -368,7 +385,11 @@ typedef unsigned int unsigned32;
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
GC_INNER void GC_notify_or_invoke_finalizers(void);
/* If GC_finalize_on_demand is not set, invoke */
/* eligible finalizers. Otherwise: */
Expand Down Expand Up @@ -1557,8 +1578,16 @@ struct _GC_arrays {
# ifdef ENABLE_DISCLAIM
# define GC_finalized_kind GC_arrays._finalized_kind
unsigned _finalized_kind;
# ifdef BUFFERED_FINALIZATION
# define GC_fin_q_kind GC_arrays._fin_q_kind
unsigned _fin_q_kind;
# define GC_finalizer_buffer_head GC_arrays._fin_buffer_head
GC_finalization_buffer_hdr* _fin_buffer_head;
# define GC_finalizer_buffer_current GC_arrays._fin_buffer_current
struct GC_current_buffer _fin_buffer_current;
# define GC_finalizer_thread_exists GC_arrays._fin_thread_exists
int _fin_thread_exists;
# endif
# endif
# define n_root_sets GC_arrays._n_root_sets
# define GC_excl_table_entries GC_arrays._excl_table_entries
Expand Down
2 changes: 2 additions & 0 deletions misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2069,9 +2069,11 @@ GC_API void GC_CALL GC_enable(void)
LOCK();
GC_ASSERT(GC_dont_gc != 0); /* ensure no counter underflow */
GC_dont_gc--;
#ifndef BUFFERED_FINALIZATION
if (!GC_dont_gc && GC_heapsize > GC_heapsize_on_gc_disable)
WARN("Heap grown by %" WARN_PRIuPTR " KiB while GC was disabled\n",
(GC_heapsize - GC_heapsize_on_gc_disable) >> 10);
#endif
UNLOCK();
}

Expand Down

0 comments on commit 9bfdaa2

Please sign in to comment.