diff --git a/src/jalloc.c b/src/jalloc.c index 4011963..25f52d3 100644 --- a/src/jalloc.c +++ b/src/jalloc.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -7,8 +6,9 @@ #define HEAP_SIZE (1024 * 1024 * 2) #define ALIGNMENT 16 -#define HEADER_SIZE 32 -#define FOOTER_SIZE 16 +#define ALIGN(size) (((size) + (ALIGNMENT - 1)) & ~(ALIGNMENT - 1)) +#define HEADER_SIZE (ALIGN(sizeof(struct Header))) +#define FOOTER_SIZE (ALIGN(sizeof(struct Footer))) struct Header { size_t size; @@ -30,6 +30,7 @@ struct Footer *footer(struct Header *hdr) { } struct Header *pop_first_fit(size_t size) { + if (free_stack == NULL) return NULL; struct Header *head = free_stack; if (head->size >= size) { free_stack = head->next_free; // remove from free stack @@ -48,6 +49,7 @@ struct Header *pop_first_fit(size_t size) { } struct Header *pop(struct Header *ptr) { + if (free_stack == NULL) return NULL; struct Header *head = free_stack; if (head == ptr) { free_stack = head->next_free; @@ -65,14 +67,9 @@ struct Header *pop(struct Header *ptr) { return NULL; } -struct Header *push_header(struct Header *hdr) { +void push_header(struct Header *hdr) { hdr->next_free = free_stack; free_stack = hdr; - return hdr; -} - -size_t next_multiple_of_align(size_t size) { - return ((size + (ALIGNMENT - 1)) >> 4) << 4; } void initialize() { @@ -80,12 +77,11 @@ void initialize() { size_t initial_block_size = HEAP_SIZE - (HEADER_SIZE + FOOTER_SIZE); // write a header struct Header *hdr = (struct Header *) heap; // first two alignment slots taken by initial header - free_stack = hdr; + hdr->is_free = true; + hdr->size = initial_block_size; + hdr->next = NULL; + hdr->next_free = NULL; push_header(hdr); - 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 = footer(hdr); ftr->header = hdr; @@ -98,7 +94,8 @@ struct Header *shrink(struct Header *hdr, size_t size) { // 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 + + if (size + HEADER_SIZE + FOOTER_SIZE > hdr->size) return hdr; 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) { @@ -129,24 +126,24 @@ 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); + size_t aligned_size = ALIGN(size); struct Header *hdr = pop_first_fit(aligned_size); if (hdr == NULL) return NULL; hdr = shrink(hdr, aligned_size); struct Footer *ftr = footer(hdr); - 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; + uint8_t* next_ptr = (uint8_t *) ftr + FOOTER_SIZE; // set next adjacent ptr + if ((uint8_t *)next_ptr >= (heap + HEAP_SIZE)) next_ptr = NULL; hdr->next = (struct Header *)next_ptr; hdr->is_free = false; ftr->header = hdr; - return (void*)hdr + HEADER_SIZE; + return (uint8_t*)hdr + HEADER_SIZE; } void jfree(void *ptr) { - struct Header *hdr = (struct Header *)(ptr-HEADER_SIZE); + if (ptr == NULL) return; + struct Header *hdr = (struct Header *)((uint8_t *)ptr-HEADER_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 @@ -166,8 +163,8 @@ void jfree(void *ptr) { if (next_hdr->is_free) { 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; + hdr->next = next_hdr->next; + if ((uint8_t *)hdr->next >= (heap + HEAP_SIZE)) hdr->next = NULL; next_ftr->header = hdr; ftr = next_ftr; }