Skip to content

Upgrade the implementation of dynamic memory allocator: #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 39 additions & 25 deletions commented_heap.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "include/heap.h"

int offset = sizeof(int) * 2;
#define USER_POINTER_OFFSET (2 * sizeof(int))

// ========================================================
// this function initializes a new heap structure, provided
Expand All @@ -10,7 +10,7 @@ int offset = sizeof(int) * 2;
// how large the heap is so make sure the same constant
// is used when allocating memory for your heap!
// ========================================================
void init_heap(heap_t *heap, int start) {
void init_heap(heap_t *heap, long start) {
// first we create the initial region, this is the "wilderness" chunk
// the heap starts as just one big chunk of allocatable memory
node_t *init_region = (node_t *) start;
Expand All @@ -34,11 +34,20 @@ void init_heap(heap_t *heap, int start) {
// if neccesary and return the start of the chunk
// ========================================================
void *heap_alloc(heap_t *heap, size_t size) {
uint index = 0;
bin_t *temp = NULL;
node_t *found = NULL;

// do alignment first
if (ALIGN_BTYES != 1) {
size = ((size + ALIGN_BTYES - 1) / ALIGN_BTYES) * ALIGN_BTYES;
}

// first get the bin index that this chunk size should be in
int index = get_bin_index(size);
index = get_bin_index(size);
// now use this bin to try and find a good fitting chunk!
bin_t *temp = (bin_t *) heap->bins[index];
node_t *found = get_best_fit(temp, size);
temp = (bin_t *) heap->bins[index];
found = get_best_fit(temp, size);

// while no chunk if found advance through the bins until we
// find a chunk or get to the wilderness
Expand Down Expand Up @@ -103,29 +112,34 @@ void *heap_alloc(heap_t *heap, size_t size) {
// coalesced and then placed in the correct bin
// ========================================================
void heap_free(heap_t *heap, void *p) {
bin_t *list;
footer_t *new_foot, *old_foot;
bin_t *list = NULL;
footer_t *new_foot = NULL;
footer_t *old_foot = NULL;
footer_t *f = NULL;
node_t *prev = NULL;
int has_next = 0;
int has_prev = 0;

// the actual head of the node is not p, it is p minus the size
// of the fields that precede "next" in the node structure
// if the node being free is the start of the heap then there is
// no need to coalesce so just put it in the right list
node_t *head = (node_t *) ((char *) p - offset);
if (head == heap->start) {
head->hole = 1;
add_node(heap->bins[get_bin_index(head->size)], head);
return;
// if the node being free is the start of the heap, it would has
// no previous node to coalesce
node_t *head = (node_t *) ((char *) p - USER_POINTER_OFFSET);
if (head != (node_t *)(uintptr_t) heap->start) {
has_prev = 1;
f = (footer_t *) ((char *) head - sizeof(footer_t));
prev = f->header;
}

// these are the next and previous nodes in the heap, not the prev and next
// in a bin. to find prev we just get subtract from the start of the head node
// to get the footer of the previous node (which gives us the header pointer).
// to get the next node we simply get the footer and add the sizeof(footer_t).
// if the node being free is the end of the heap, it would has
// no next node to coalesce
node_t *next = (node_t *) ((char *) get_foot(head) + sizeof(footer_t));
node_t *prev = (node_t *) * ((int *) ((char *) head - sizeof(footer_t)));
if (next != (node_t *) (uintptr_t)heap->end) {
has_next = 1;
}

// if the previous node is a hole we can coalese!
if (prev->hole) {
// if it has the previous node and the previous node is a hole we can coalese!
if (has_prev && prev->hole) {
// remove the previous node from its bin
list = heap->bins[get_bin_index(prev->size)];
remove_node(list, prev);
Expand All @@ -140,8 +154,8 @@ void heap_free(heap_t *heap, void *p) {
head = prev;
}

// if the next node is free coalesce!
if (next->hole) {
// if it has the next node and the next node is free coalesce!
if (has_next && next->hole) {
// remove it from its bin
list = heap->bins[get_bin_index(next->size)];
remove_node(list, next);
Expand All @@ -165,7 +179,7 @@ void heap_free(heap_t *heap, void *p) {
}

// these are left here to implement contraction / expansion
int expand(heap_t *heap, size_t sz) {
uint expand(heap_t *heap, size_t sz) {

}

Expand All @@ -179,7 +193,7 @@ void contract(heap_t *heap, size_t sz) {
// places any allocation < 8 in bin 0 and then for anything
// above 8 it bins using the log base 2 of the size
// ========================================================
int get_bin_index(size_t sz) {
uint get_bin_index(size_t sz) {
int index = 0;
sz = sz < 4 ? 4 : sz;

Expand Down
46 changes: 30 additions & 16 deletions heap.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "include/heap.h"
#include "include/llist.h"

uint offset = 8;
#define USER_POINTER_OFFSET (2 * sizeof(int))

void init_heap(heap_t *heap, long start) {
node_t *init_region = (node_t *) start;
Expand All @@ -17,9 +17,17 @@ void init_heap(heap_t *heap, long start) {
}

void *heap_alloc(heap_t *heap, size_t size) {
uint index = get_bin_index(size);
bin_t *temp = (bin_t *) heap->bins[index];
node_t *found = get_best_fit(temp, size);
uint index = 0;
bin_t *temp = NULL;
node_t *found = NULL;

if (ALIGN_BTYES != 1) {
size = ((size + ALIGN_BTYES - 1) / ALIGN_BTYES) * ALIGN_BTYES;
}

index = get_bin_index(size);
temp = (bin_t *) heap->bins[index];
found = get_best_fit(temp, size);

while (found == NULL) {
if (index + 1 >= BIN_COUNT)
Expand Down Expand Up @@ -64,21 +72,27 @@ void *heap_alloc(heap_t *heap, size_t size) {
}

void heap_free(heap_t *heap, void *p) {
bin_t *list;
footer_t *new_foot, *old_foot;

node_t *head = (node_t *) ((char *) p - offset);
if (head == (node_t *) (uintptr_t) heap->start) {
head->hole = 1;
add_node(heap->bins[get_bin_index(head->size)], head);
return;
bin_t *list = NULL;
footer_t *new_foot = NULL;
footer_t *old_foot = NULL;
footer_t *f = NULL;
node_t *prev = NULL;
int has_next = 0;
int has_prev = 0;

node_t *head = (node_t *) ((char *) p - USER_POINTER_OFFSET);
if (head != (node_t *)(uintptr_t) heap->start) {
has_prev = 1;
f = (footer_t *) ((char *) head - sizeof(footer_t));
prev = f->header;
}

node_t *next = (node_t *) ((char *) get_foot(head) + sizeof(footer_t));
footer_t *f = (footer_t *) ((char *) head - sizeof(footer_t));
node_t *prev = f->header;
if (next != (node_t *) (uintptr_t)heap->end) {
has_next = 1;
}

if (prev->hole) {
if (has_prev && prev->hole) {
list = heap->bins[get_bin_index(prev->size)];
remove_node(list, prev);

Expand All @@ -89,7 +103,7 @@ void heap_free(heap_t *heap, void *p) {
head = prev;
}

if (next->hole) {
if (has_next && next->hole) {
list = heap->bins[get_bin_index(next->size)];
remove_node(list, next);

Expand Down
3 changes: 3 additions & 0 deletions include/heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#define BIN_COUNT 9
#define BIN_MAX_IDX (BIN_COUNT - 1)

#define ALIGN_BTYES sizeof(long) /* alignment bytes */

typedef unsigned int uint;

typedef struct node_t {
Expand Down Expand Up @@ -49,6 +51,7 @@ uint expand(heap_t *heap, size_t sz);
void contract(heap_t *heap, size_t sz);

uint get_bin_index(size_t sz);
node_t *get_best_fit(bin_t *bin, size_t size);
void create_foot(node_t *head);
footer_t *get_foot(node_t *head);

Expand Down
16 changes: 8 additions & 8 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,26 @@ int main(int argc, char** argv) {
printf("overhead = %d \n", overhead);

void *a = heap_alloc(heap, 8);
printf("a = %d size: 8 \n", (int) a);
printf("a = %p size: 8 \n", a);
void *b = heap_alloc(heap, 128);
printf("b = %d size: 128 \n", (int) b);
printf("b = %p size: 128 \n", b);
void *c = heap_alloc(heap, 8);
printf("c = %d size: 8 \n", (int) c);
printf("c = %p size: 8 \n", c);

printf("\nfreeing b \n");
heap_free(heap, b);

void* d = heap_alloc(heap, 8);
printf("d = %d size: 8 \n", (int) d);
printf("d = %p size: 8 \n", d);

void* e = heap_alloc(heap, 16);
printf("e = %d size: 16 \n", (int) e);
printf("e = %p size: 16 \n", e);

void* f = heap_alloc(heap, 8);
printf("f = %d size: 8 \n", (int) f);
printf("f = %p size: 8 \n", f);

void* g = heap_alloc(heap, 8);
printf("g = %d size: 8 \n", (int) g);
printf("g = %p size: 8 \n", g);

printf("\nfreeing d & f \n");
heap_free(heap, d);
Expand All @@ -51,7 +51,7 @@ int main(int argc, char** argv) {
heap_free(heap, e);

void* h = heap_alloc(heap, 128);
printf("h = %d size: 128 \n", (int) h);
printf("h = %p size: 128 \n", h);
printf("\n");

for (i = 1; i <= 2048; i += i) printf("size: %d -> bin: %d \n", i, get_bin_index(i));
Expand Down