malloc: added destroy_heap function

This commit is contained in:
Andrew Scott 2024-09-18 17:22:21 -04:00
parent 3ecb5d560f
commit e8f5fa88b5
Signed by: a
GPG key ID: 7CD5A5977E4931C1
2 changed files with 39 additions and 6 deletions

View file

@ -45,13 +45,13 @@ struct gc_chunk *find_prev_chunk(struct gc_chunk *curr);
void set_footer(struct gc_chunk *curr); void set_footer(struct gc_chunk *curr);
// Gets footer information for the current chunk - useful for debugging // 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 // Creates a new chunk with sentinel
struct gc_chunk *init_gc_chunk(void); struct gc_chunk *init_gc_chunk(void);
// Gets a pointer to a suitable chunk from the free list, otherwise creates a // Gets a pointer to a suitable chunk (first fit) from the free list, otherwise
// new chunk and returns it's pointer // creates a new chunk and returns it's pointer
struct gc_chunk *find_free_chunk(size_t size); struct gc_chunk *find_free_chunk(size_t size);
// Coalesces chunks when merge flag is set // Coalesces chunks when merge flag is set
@ -60,7 +60,10 @@ void merge_chunk(struct gc_chunk *curr);
// Performs allocations of SIZE bytes // Performs allocations of SIZE bytes
void *gc_malloc(size_t size); void *gc_malloc(size_t size);
// Frees blocks of memory allocated by 'gc_alloc' // Frees allocations for re-use
void gc_free(void *ptr); 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 */ #endif /* GC_MALLOC_H */

View file

@ -1,12 +1,18 @@
#include <assert.h> #include <assert.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <unistd.h> #include <unistd.h>
#include "gc_malloc.h" #include "gc_malloc.h"
/* Static Variables */
// Doubly linked list to keep track of free chunks
static struct gc_chunk *freelist = NULL; static struct gc_chunk *freelist = NULL;
/* Static Inline Functions */
// Hides chunk header // Hides chunk header
static inline void *hide(struct gc_chunk *curr) static inline void *hide(struct gc_chunk *curr)
{ {
@ -43,6 +49,8 @@ static inline uint32_t align(uint32_t size)
return size; return size;
} }
/* Debug Functions */
// Useful for debugging after find or merge are called // Useful for debugging after find or merge are called
static void chk_freelist(void) 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) struct gc_chunk *find_next_chunk(struct gc_chunk *curr)
{ {
unsigned size = curr->size; unsigned size = curr->size;
@ -82,7 +92,7 @@ void set_footer(struct gc_chunk *curr)
next->footer = curr->size; 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); struct gc_chunk *next = find_next_chunk(curr);
return next->footer; return next->footer;
@ -119,8 +129,12 @@ struct gc_chunk *init_gc_chunk(void)
struct gc_chunk *find_free_chunk(size_t size) 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 // 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; return NULL;
}
struct gc_chunk *found; struct gc_chunk *found;
@ -151,6 +165,7 @@ struct gc_chunk *find_free_chunk(size_t size)
return found; return found;
} }
// FIXME: need to clean up todos before this will work
void merge_chunk(struct gc_chunk *curr) void merge_chunk(struct gc_chunk *curr)
{ {
if (curr->merge) { if (curr->merge) {
@ -201,3 +216,18 @@ void gc_free(void *ptr)
chk_freelist(); // TODO: Remove this line after debugging 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;
}
}