mirror of
https://codeberg.org/andyscott/marCsweep.git
synced 2024-12-22 01:33:11 -05:00
malloc: defined gc_malloc
, gc_free
, and debug func chk_freelist
This commit is contained in:
parent
5749c68035
commit
3ecb5d560f
1 changed files with 58 additions and 5 deletions
|
@ -19,8 +19,9 @@ static inline struct gc_chunk *magic(void *mem)
|
|||
return (struct gc_chunk *)((uint64_t *)mem - MAGIC);
|
||||
}
|
||||
|
||||
// Aligns the amount of memory requested by the user with chunk size
|
||||
/*
|
||||
* Aligns the amount of memory requested by the user with chunk size
|
||||
*
|
||||
* Example: User requests 1 byte
|
||||
* LHS
|
||||
* requested size = 0b00000001
|
||||
|
@ -42,6 +43,26 @@ static inline uint32_t align(uint32_t size)
|
|||
return size;
|
||||
}
|
||||
|
||||
// Useful for debugging after find or merge are called
|
||||
static void chk_freelist(void)
|
||||
{
|
||||
struct gc_chunk *next = freelist;
|
||||
struct gc_chunk *prev = NULL;
|
||||
|
||||
while (next != NULL) {
|
||||
assert(next->free);
|
||||
assert(next->merge == 0);
|
||||
assert(next->size >= MIN);
|
||||
assert(get_footer(next) == next->size);
|
||||
assert(next->prev == prev);
|
||||
struct gc_chunk *after = find_next_chunk(next);
|
||||
assert(after->merge == 1);
|
||||
assert(after->free == 0);
|
||||
prev = next;
|
||||
next = next->next;
|
||||
}
|
||||
}
|
||||
|
||||
struct gc_chunk *find_next_chunk(struct gc_chunk *curr)
|
||||
{
|
||||
unsigned size = curr->size;
|
||||
|
@ -69,8 +90,7 @@ int get_footer(struct gc_chunk *curr)
|
|||
|
||||
struct gc_chunk *init_gc_chunk(void)
|
||||
{
|
||||
const size_t page_size = getpagesize();
|
||||
const size_t len = page_size * sizeof(uint64_t);
|
||||
const size_t len = getpagesize();
|
||||
struct gc_chunk *chunk =
|
||||
(struct gc_chunk *)mmap(NULL, len, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
|
@ -78,7 +98,7 @@ struct gc_chunk *init_gc_chunk(void)
|
|||
if (chunk == MAP_FAILED)
|
||||
return NULL;
|
||||
|
||||
chunk->size = page_size - MAGIC - OVERHEAD;
|
||||
chunk->size = len - MAGIC - OVERHEAD;
|
||||
chunk->merge = 0;
|
||||
chunk->free = 1;
|
||||
chunk->next = NULL;
|
||||
|
@ -92,11 +112,16 @@ struct gc_chunk *init_gc_chunk(void)
|
|||
sentinel->next = NULL;
|
||||
sentinel->prev = chunk;
|
||||
|
||||
chk_freelist(); // TODO: Remove this line after debugging
|
||||
return chunk;
|
||||
}
|
||||
|
||||
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())
|
||||
return NULL;
|
||||
|
||||
struct gc_chunk *found;
|
||||
|
||||
while (1) {
|
||||
|
@ -104,6 +129,7 @@ struct gc_chunk *find_free_chunk(size_t size)
|
|||
while (found != NULL) {
|
||||
if (found->size >= size) {
|
||||
// found, TODO: split when appropriate
|
||||
// remaining block needs to be at least MIN + OVERHEAD
|
||||
break;
|
||||
}
|
||||
found = found->next;
|
||||
|
@ -129,7 +155,9 @@ void merge_chunk(struct gc_chunk *curr)
|
|||
{
|
||||
if (curr->merge) {
|
||||
struct gc_chunk *prev = find_prev_chunk(curr);
|
||||
chk_freelist(); // TODO: Remove this line after debugging
|
||||
struct gc_chunk *next = find_next_chunk(curr);
|
||||
chk_freelist(); // TODO: Remove this line after debugging
|
||||
if (next->free) {
|
||||
// TODO Case 1: merge prev and next
|
||||
|
||||
|
@ -139,6 +167,7 @@ void merge_chunk(struct gc_chunk *curr)
|
|||
set_footer(prev);
|
||||
} else {
|
||||
struct gc_chunk *next = find_next_chunk(curr);
|
||||
chk_freelist(); // TODO: Remove this line after debugging
|
||||
if (next->free) {
|
||||
// TODO Case 3: merge with after
|
||||
} else {
|
||||
|
@ -148,3 +177,27 @@ void merge_chunk(struct gc_chunk *curr)
|
|||
set_footer(curr);
|
||||
}
|
||||
}
|
||||
|
||||
void *gc_malloc(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return NULL;
|
||||
|
||||
uint32_t bytes = align(size);
|
||||
struct gc_chunk *curr = find_free_chunk(bytes);
|
||||
chk_freelist(); // TODO: Remove this line after debugging
|
||||
|
||||
if (curr == NULL)
|
||||
return curr;
|
||||
|
||||
return hide(curr);
|
||||
}
|
||||
|
||||
void gc_free(void *ptr)
|
||||
{
|
||||
if (ptr != NULL) {
|
||||
struct gc_chunk *curr = magic(ptr);
|
||||
merge_chunk(curr);
|
||||
chk_freelist(); // TODO: Remove this line after debugging
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue