mirror of
https://codeberg.org/andyscott/marCsweep.git
synced 2024-11-09 22:01:01 -05:00
malloc: added destroy_heap
function
This commit is contained in:
parent
3ecb5d560f
commit
e8f5fa88b5
2 changed files with 39 additions and 6 deletions
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue