Skip to content

Commit

Permalink
Bugfix/retry and allocation (#52)
Browse files Browse the repository at this point in the history
* Fix self-deletion of ptr
* Enable root creation in client API
  • Loading branch information
mkirchner committed Feb 13, 2020
1 parent 99bd443 commit aa1c069
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 18 deletions.
38 changes: 20 additions & 18 deletions src/gc.c
Expand Up @@ -339,15 +339,24 @@ static void* gc_mcalloc(size_t count, size_t size)
return calloc(count, size);
}

static bool gc_needs_sweep(GarbageCollector* gc)
{
return gc->allocs->size > gc->allocs->sweep_limit;
}

static void* gc_allocate(GarbageCollector* gc, size_t count, size_t size, void(*dtor)(void*))
{
/* Allocation logic that generalizes over malloc/calloc. */

/* Attempt to allocate memory */
/* Check if we reached the high-water mark and need to clean up */
if (gc_needs_sweep(gc) && !gc->paused) {
size_t freed_mem = gc_run(gc);
LOG_DEBUG("Garbage collection cleaned up %lu bytes.", freed_mem);
}
/* With cleanup out of the way, attempt to allocate memory */
void* ptr = gc_mcalloc(count, size);
size_t alloc_size = count ? count * size : size;
/* If allocation fails, attempt to free some memory and try again. */
/* If allocation fails, force an out-of-policy run to free some memory and try again. */
if (!ptr && !gc->paused && (errno == EAGAIN || errno == ENOMEM)) {
gc_run(gc);
ptr = gc_mcalloc(count, size);
Expand All @@ -359,24 +368,11 @@ static void* gc_allocate(GarbageCollector* gc, size_t count, size_t size, void(*
/* Deal with metadata allocation failure */
if (alloc) {
LOG_DEBUG("Managing %zu bytes at %p", alloc_size, (void*) alloc->ptr);
if (gc->allocs->size > gc->allocs->sweep_limit && !gc->paused) {
size_t freed_mem = gc_run(gc);
LOG_DEBUG("Garbage collection cleaned up %lu bytes.", freed_mem);
}
ptr = alloc->ptr;
} else {
/* We failed to allocate the metadata, give it another try or at least
* attempt to fail cleanly. */
if (!gc->paused) {
gc_run(gc);
}
alloc = gc_allocation_map_put(gc->allocs, ptr, alloc_size, dtor);
if (alloc) {
ptr = alloc->ptr;
} else {
free(ptr);
ptr = NULL;
}
/* We failed to allocate the metadata, fail cleanly. */
free(ptr);
ptr = NULL;
}
}
return ptr;
Expand All @@ -402,6 +398,12 @@ void* gc_malloc_static(GarbageCollector* gc, size_t size, void(*dtor)(void*))
return ptr;
}

void* gc_make_static(GarbageCollector* gc, void* ptr)
{
gc_make_root(gc, ptr);
return ptr;
}

void* gc_malloc_ext(GarbageCollector* gc, size_t size, void(*dtor)(void*))
{
return gc_allocate(gc, 0, size, dtor);
Expand Down
5 changes: 5 additions & 0 deletions src/gc.h
Expand Up @@ -43,6 +43,11 @@ void* gc_calloc_ext(GarbageCollector* gc, size_t count, size_t size, void (*dtor
void* gc_realloc(GarbageCollector* gc, void* ptr, size_t size);
void gc_free(GarbageCollector* gc, void* ptr);

/*
* Lifecycle management
*/
void* gc_make_static(GarbageCollector* gc, void* ptr);

/*
* Helper functions and stdlib replacements.
*/
Expand Down

0 comments on commit aa1c069

Please sign in to comment.