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);
// 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 */

View file

@ -1,12 +1,18 @@
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#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;
}
}