From e8f5fa88b59afe9be99a2b03e65293e0bcbb924b Mon Sep 17 00:00:00 2001 From: Andrew Scott Date: Wed, 18 Sep 2024 17:22:21 -0400 Subject: [PATCH] malloc: added `destroy_heap` function --- include/gc_malloc.h | 11 +++++++---- src/gc_malloc.c | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/include/gc_malloc.h b/include/gc_malloc.h index b3c97b0..d6660f4 100644 --- a/include/gc_malloc.h +++ b/include/gc_malloc.h @@ -45,13 +45,13 @@ struct gc_chunk *find_prev_chunk(struct gc_chunk *curr); void set_footer(struct gc_chunk *curr); // Gets footer information for the current chunk - useful for debugging -int get_footer(struct gc_chunk *curr); +uint64_t get_footer(struct gc_chunk *curr); // Creates a new chunk with sentinel struct gc_chunk *init_gc_chunk(void); -// Gets a pointer to a suitable chunk from the free list, otherwise creates a -// new chunk and returns it's pointer +// Gets a pointer to a suitable chunk (first fit) from the free list, otherwise +// creates a new chunk and returns it's pointer struct gc_chunk *find_free_chunk(size_t size); // Coalesces chunks when merge flag is set @@ -60,7 +60,10 @@ void merge_chunk(struct gc_chunk *curr); // Performs allocations of SIZE bytes void *gc_malloc(size_t size); -// Frees blocks of memory allocated by 'gc_alloc' +// Frees allocations for re-use void gc_free(void *ptr); +// Completely de-allocates the heap (break glass in case of emergency) +void destroy_heap(struct gc_chunk *freelist); + #endif /* GC_MALLOC_H */ diff --git a/src/gc_malloc.c b/src/gc_malloc.c index 1f27382..8efb5b2 100644 --- a/src/gc_malloc.c +++ b/src/gc_malloc.c @@ -1,12 +1,18 @@ #include #include +#include #include #include #include "gc_malloc.h" +/* Static Variables */ + +// Doubly linked list to keep track of free chunks static struct gc_chunk *freelist = NULL; +/* Static Inline Functions */ + // Hides chunk header static inline void *hide(struct gc_chunk *curr) { @@ -43,6 +49,8 @@ static inline uint32_t align(uint32_t size) return size; } +/* Debug Functions */ + // Useful for debugging after find or merge are called static void chk_freelist(void) { @@ -63,6 +71,8 @@ static void chk_freelist(void) } } +/* gc_malloc Functions */ + struct gc_chunk *find_next_chunk(struct gc_chunk *curr) { unsigned size = curr->size; @@ -82,7 +92,7 @@ void set_footer(struct gc_chunk *curr) next->footer = curr->size; } -int get_footer(struct gc_chunk *curr) +uint64_t get_footer(struct gc_chunk *curr) { struct gc_chunk *next = find_next_chunk(curr); return next->footer; @@ -119,8 +129,12 @@ struct gc_chunk *init_gc_chunk(void) struct gc_chunk *find_free_chunk(size_t size) { // HACK: The first loop will run forever if we can never get a big enough chunk - if (size > getpagesize()) + const size_t page = getpagesize(); + if (size > page) { + fprintf(stderr, + "ERROR: find_free_chunk: Requested size is larger than a page!"); return NULL; + } struct gc_chunk *found; @@ -151,6 +165,7 @@ struct gc_chunk *find_free_chunk(size_t size) return found; } +// FIXME: need to clean up todos before this will work void merge_chunk(struct gc_chunk *curr) { if (curr->merge) { @@ -201,3 +216,18 @@ void gc_free(void *ptr) chk_freelist(); // TODO: Remove this line after debugging } } + +void destroy_heap(struct gc_chunk *freelist) +{ + if (freelist == NULL) { + fprintf(stderr, "WARN: destroy_heap: Free list is empty?"); + return; + } + + struct gc_chunk *curr = freelist; + while (curr->size != 0) { + struct gc_chunk *next = curr->next; + munmap(curr, curr->size); + curr = curr->next; + } +}