wip linkedlist
This commit is contained in:
parent
9622487008
commit
8af978556a
1 changed files with 138 additions and 10 deletions
148
src/jalloc.c
148
src/jalloc.c
|
|
@ -1,16 +1,15 @@
|
|||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define HEAP_SIZE (1024 * 1024 * 2)
|
||||
#define ALIGNMENT 16
|
||||
#define HEADER_SIZE 32
|
||||
#define FOOTER_SIZE 16
|
||||
|
||||
static uint8_t heap[HEAP_SIZE];
|
||||
static uint8_t *heap_ptr = heap;
|
||||
|
||||
struct Header {
|
||||
size_t size;
|
||||
bool is_free;
|
||||
|
|
@ -21,38 +20,156 @@ 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 bool initialized = false;
|
||||
|
||||
|
||||
|
||||
struct Footer *footer(struct Header *hdr) {
|
||||
return (struct Footer *)((uint8_t *)hdr + 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
|
||||
return head;
|
||||
}
|
||||
while (head != NULL) {
|
||||
struct Block *next = head->next;
|
||||
if (next == NULL) return NULL;
|
||||
if (next->header->size >= size) {
|
||||
head->next = next->next; // remove from free stack
|
||||
return next;
|
||||
}
|
||||
head = next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct Block *pop(struct Block *ptr) {
|
||||
struct Block *head = free_stack;
|
||||
if (head == ptr) {
|
||||
free_stack = head->next;
|
||||
return head;
|
||||
}
|
||||
while (head != NULL) {
|
||||
struct Block *next = head->next;
|
||||
if (next == NULL) break; // if next is NULL, deref below will fault
|
||||
if (next == ptr) {
|
||||
head->next = next->next;
|
||||
return 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;
|
||||
}
|
||||
|
||||
size_t next_multiple_of_align(size_t size) {
|
||||
return ((size + (ALIGNMENT - 1)) >> 4) << 4;
|
||||
}
|
||||
|
||||
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
|
||||
push_header(hdr);
|
||||
free_stack->header->is_free = true;
|
||||
free_stack->header->size = initial_block_size;
|
||||
free_stack->header->next = NULL;
|
||||
free_stack->next = NULL;
|
||||
// write a footer to heap
|
||||
struct Footer *ftr = (struct Footer *) (heap + initial_block_size - ALIGNMENT);
|
||||
ftr->header = hdr;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
struct Block *shrink(struct Block *ptr, 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) {
|
||||
hdr->size = size; // resize left block
|
||||
// create our footer
|
||||
struct Footer *ftr = footer(hdr);
|
||||
ftr->header = hdr;
|
||||
// create next header
|
||||
struct Header *next_hdr = (struct Header *)((uint8_t *)ftr + FOOTER_SIZE);
|
||||
next_hdr->size = other_size;
|
||||
next_hdr->is_free = true;
|
||||
next_hdr->next = hdr->next;
|
||||
hdr->next = next_hdr;
|
||||
// create next footer
|
||||
struct Footer *next_ftr = footer(next_hdr);
|
||||
next_ftr->header = next_hdr;
|
||||
|
||||
// push new block to stack
|
||||
push_header(next_hdr);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate memory via bump 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);
|
||||
void *ptr = heap_ptr + HEADER_SIZE;
|
||||
struct Header *hdr = (struct Header *)heap_ptr;
|
||||
struct Footer *ftr = (struct Footer *)(ptr + aligned_size);
|
||||
if ((uint8_t *)ftr + FOOTER_SIZE > (uint8_t *)heap + sizeof(heap)) return NULL;
|
||||
heap_ptr = (void *) ftr + FOOTER_SIZE; // set next ptr
|
||||
struct Block *blk = pop_first_fit(aligned_size);
|
||||
if (blk == NULL) return NULL;
|
||||
|
||||
blk = shrink(blk, aligned_size);
|
||||
|
||||
struct Header *hdr = blk->header;
|
||||
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;
|
||||
hdr->size = aligned_size;
|
||||
hdr->next = (struct Header *)heap_ptr;
|
||||
hdr->is_free = false;
|
||||
ftr->header = hdr;
|
||||
return ptr;
|
||||
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);
|
||||
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");
|
||||
prev_hdr->size += hdr->size + HEADER_SIZE + FOOTER_SIZE;
|
||||
prev_hdr->next=hdr->next;
|
||||
ftr->header=prev_hdr;
|
||||
|
|
@ -60,13 +177,24 @@ void jfree(void *ptr) {
|
|||
}
|
||||
}
|
||||
if (hdr->next != NULL) {
|
||||
printf("checking coalescing right\n\n");
|
||||
struct Header *next_hdr = hdr->next;
|
||||
struct Footer *next_ftr = (struct Footer *) ((uint8_t *)next_hdr + next_hdr->size);
|
||||
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");
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue