From 1f058f0c4ec0be992150f32b74831ffd2a50c12e Mon Sep 17 00:00:00 2001 From: jackjohn7 <70782491+jackjohn7@users.noreply.github.com> Date: Wed, 17 Jun 2026 01:10:19 -0500 Subject: [PATCH] feat: working and refactored to remove dedicated linked-list in favor of just using the headers --- src/jalloc.c | 100 ++++++++++++++++++++------------------------------- 1 file changed, 38 insertions(+), 62 deletions(-) diff --git a/src/jalloc.c b/src/jalloc.c index d771493..4011963 100644 --- a/src/jalloc.c +++ b/src/jalloc.c @@ -14,38 +14,32 @@ struct Header { size_t size; bool is_free; struct Header *next; + struct Header *next_free; }; struct Footer { struct Header *header; }; -struct Block { - struct Header *header; - struct Block *next; -}; - static uint8_t heap[HEAP_SIZE]; -static struct Block *free_stack; +static struct Header *free_stack; static bool initialized = false; - - struct Footer *footer(struct Header *hdr) { - return (struct Footer *)((uint8_t *)hdr + hdr->size); + return (struct Footer *)((uint8_t *)hdr + HEADER_SIZE + hdr->size); } -struct Block *pop_first_fit(size_t size) { - struct Block *head = free_stack; - if (head->header->size >= size) { - free_stack = head->next; // remove from free stack +struct Header *pop_first_fit(size_t size) { + struct Header *head = free_stack; + if (head->size >= size) { + free_stack = head->next_free; // remove from free stack return head; } while (head != NULL) { - struct Block *next = head->next; + struct Header *next = head->next_free; if (next == NULL) return NULL; - if (next->header->size >= size) { - head->next = next->next; // remove from free stack + if (next->size >= size) { + head->next_free = next->next_free; // remove from free stack return next; } head = next; @@ -53,32 +47,28 @@ struct Block *pop_first_fit(size_t size) { return NULL; } -struct Block *pop(struct Block *ptr) { - struct Block *head = free_stack; +struct Header *pop(struct Header *ptr) { + struct Header *head = free_stack; if (head == ptr) { - free_stack = head->next; + free_stack = head->next_free; return head; } while (head != NULL) { - struct Block *next = head->next; + struct Header *next = head->next_free; if (next == NULL) break; // if next is NULL, deref below will fault if (next == ptr) { - head->next = next->next; + head->next_free = next->next_free; return next; } + head = next; } return NULL; } -struct Block *push_header(struct Header *hdr) { - struct Block *blk = malloc(sizeof(struct Block)); - blk->header = hdr; - blk->next = free_stack; - free_stack = blk; -} - -struct Block *pop_header(struct Header *ptr) { - return NULL; +struct Header *push_header(struct Header *hdr) { + hdr->next_free = free_stack; + free_stack = hdr; + return hdr; } size_t next_multiple_of_align(size_t size) { @@ -88,28 +78,27 @@ size_t next_multiple_of_align(size_t size) { void initialize() { // initialize the free list to be a single element containing the entire block size_t initial_block_size = HEAP_SIZE - (HEADER_SIZE + FOOTER_SIZE); - free_stack = malloc(sizeof(struct Block)); // write a header struct Header *hdr = (struct Header *) heap; // first two alignment slots taken by initial header + free_stack = hdr; push_header(hdr); - free_stack->header->is_free = true; - free_stack->header->size = initial_block_size; - free_stack->header->next = NULL; + free_stack->is_free = true; + free_stack->size = initial_block_size; free_stack->next = NULL; + free_stack->next_free = NULL; // write a footer to heap - struct Footer *ftr = (struct Footer *) (heap + initial_block_size - ALIGNMENT); + struct Footer *ftr = footer(hdr); ftr->header = hdr; initialized = true; } -struct Block *shrink(struct Block *ptr, size_t size) { +struct Header *shrink(struct Header *hdr, size_t size) { // given a size, shrink a block down to the appropriate alignment. // if align(size) + ALIGNMENT*3 is equal to current size, just return initial ptr with noop // otherwise, shrink it down so that we have two blocks. // Push the right block to the free stack // Return left block size = next_multiple_of_align(size); // align if not already so - struct Header *hdr = ptr->header; size_t other_size = hdr->size-size-(HEADER_SIZE + FOOTER_SIZE); // if we have space for a full alignment, then a single block of 16 bytes can be allocated there if (other_size >= ALIGNMENT) { @@ -130,46 +119,41 @@ struct Block *shrink(struct Block *ptr, size_t size) { // push new block to stack push_header(next_hdr); } - return ptr; + return hdr; } /** - * Allocate memory via bump allocation + * Allocate memory via free-list allocation */ void *jalloc(size_t size) { if (!initialized) initialize(); // Total size of allocation = HEADER(padded to ALIGNMENT) + size(padded to ALIGNMENT) + FOOTER(padded to ALIGNMENT) size_t aligned_size = next_multiple_of_align(size); - struct Block *blk = pop_first_fit(aligned_size); - if (blk == NULL) return NULL; + struct Header *hdr = pop_first_fit(aligned_size); + if (hdr == NULL) return NULL; - blk = shrink(blk, aligned_size); - - struct Header *hdr = blk->header; + hdr = shrink(hdr, aligned_size); struct Footer *ftr = footer(hdr); - uint8_t* heap_ptr = (void *) ftr + FOOTER_SIZE; // set next ptr - if ((uint8_t *)heap_ptr > (heap + HEAP_SIZE)) heap_ptr = NULL; + + uint8_t* next_ptr = (void *) ftr + FOOTER_SIZE; // set next adjacent ptr + if ((uint8_t *)next_ptr > (heap + HEAP_SIZE)) next_ptr = NULL; hdr->size = aligned_size; - hdr->next = (struct Header *)heap_ptr; + hdr->next = (struct Header *)next_ptr; hdr->is_free = false; ftr->header = hdr; return (void*)hdr + HEADER_SIZE; } void jfree(void *ptr) { - printf("freeing\n\n"); struct Header *hdr = (struct Header *)(ptr-HEADER_SIZE); - struct Footer *ftr = (struct Footer *)((uint8_t *)hdr+hdr->size); + struct Footer *ftr = footer(hdr); hdr->is_free = true; if ((uint8_t *)hdr > heap) { // if this is greater, then there ought to be a foot to the left - printf("checking coalescing left\n\n"); struct Footer *prev_ftr = (struct Footer *)((uint8_t *)hdr-FOOTER_SIZE); struct Header *prev_hdr = prev_ftr->header; if (prev_hdr->is_free) { - printf("coalescing left\n\n"); - pop_header(prev_hdr); - printf("header popped\n\n"); + pop(prev_hdr); prev_hdr->size += hdr->size + HEADER_SIZE + FOOTER_SIZE; prev_hdr->next=hdr->next; ftr->header=prev_hdr; @@ -177,24 +161,16 @@ void jfree(void *ptr) { } } if (hdr->next != NULL) { - printf("checking coalescing right\n\n"); struct Header *next_hdr = hdr->next; struct Footer *next_ftr = footer(next_hdr); - assert(next_ftr != NULL); - assert(next_ftr->header != NULL); if (next_hdr->is_free) { - printf("coalescing right\n\n"); - pop_header(next_hdr); - printf("header popped\n\n"); + pop(next_hdr); hdr->size += next_hdr->size + HEADER_SIZE + FOOTER_SIZE; hdr->next = (struct Header *) ((uint8_t*)next_ftr + FOOTER_SIZE); if ((uint8_t *)hdr->next > (heap + HEAP_SIZE)) hdr->next = NULL; - printf("set next\n\n"); - printf("next ftr?: %s\n\n", (uint8_t*)next_ftr); next_ftr->header = hdr; ftr = next_ftr; } } - printf("pushing free header\n\n"); push_header(hdr); }