Refactor to holding linked list data before the alloced blocks.

These "tags" hold the pointers between the alloced blocks.
This commit is contained in:
Maxime Bloch 2020-01-28 18:04:46 +01:00
parent ea9f4c6e49
commit fafe06ed2b
No known key found for this signature in database
GPG key ID: CE32A7D95B7D6418
2 changed files with 102 additions and 118 deletions

View file

@ -290,7 +290,7 @@ repnz movsd
or ax, ax or ax, ax
jnz .elf_ph_loop jnz .elf_ph_loop
.start_kernel .start_kernel:
cmp edi, KERNEL_START cmp edi, KERNEL_START
je .invalid_elf je .invalid_elf

View file

@ -5,159 +5,143 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
typedef struct ll_node { typedef struct page_tag {
void *data; size_t size;
int size;
bool used;
struct ll_node *previous; struct page_tag *prev;
struct ll_node *next; struct page_tag *next;
} ll_node; } page_tag;
ll_node *__new_node() {
ll_node *new_node = malloc(sizeof(ll_node));
new_node->data = NULL;
new_node->size = 0;
new_node->used = false;
new_node->previous = NULL; page_tag *start;
new_node->next = NULL;
return new_node;
}
ll_node *__search_ll_node(ll_node *heap_head, void *data) {
ll_node *curr_node = heap_head; page_tag *__searchPage(void *data) {
while (!curr_node->used || curr_node->data != data) { page_tag *curr_page = start;
curr_node = curr_node->next; while (curr_page + (sizeof(page_tag)) != data) {
curr_page = curr_page->next;
} }
return curr_node; return curr_page;
} }
void *__alloc(ll_node *ll_head, int size) { ///**
ll_node *curr_node = ll_head; // * @param alignment
ll_node *new_node = __new_node(); // * @param size
new_node->used = true; // * @return A block aligned with the alignment parameter.
new_node->size = size; // */
//void* aligned_alloc(int alignment, int size){
// // TODO
// return NULL;
//}
while (curr_node->next != NULL) { void *__alloc(size_t size) {
curr_node = curr_node->next; page_tag *curr_page = start;
if (!curr_node->used && curr_node->size >= size) { while (curr_page->next != NULL) {
curr_node->size -= size; page_tag *new_page = ((void *) curr_page) + sizeof(page_tag) + curr_page->size;
if ((void *) new_page + sizeof(page_tag) + size <= curr_page->next) {
// xxx -> <new_node> -> empty block -> yyy new_page->size = size;
// link new_node to xxx curr_page->next->prev = new_page;
curr_node->previous->next = new_node; new_page->next = curr_page->next;
new_node->previous = curr_node->previous;
// link new_node to empty_block or yyy curr_page->next = new_page;
if (curr_node->size == 0) { new_page->prev = curr_page;
new_node->next = curr_node->next;
curr_node->next->previous = new_node;
free(curr_node);
} else {
new_node->next = curr_node;
curr_node->previous = new_node;
}
void *data = new_node->previous->data + new_node->previous->size; return new_page + 1;
new_node->data = data;
return new_node->data;
} }
curr_page = curr_page->next;
} }
new_node->previous = curr_node;
curr_node->next = new_node;
void *data = new_node->previous->data + new_node->previous->size; page_tag *new_page = ((void *) curr_page) + sizeof(page_tag) + curr_page->size;
new_node->data = data; new_page->size = size;
return new_node->data;
curr_page->next = new_page;
new_page->prev = curr_page;
return new_page + 1;
} }
void __free(ll_node *ll_head, void *data) { void __free(void *data) {
// Search the corresponding block of memory page_tag *data_tag = data - sizeof(page_tag);
// TODO This can be held in a table for quicker lookup printf("found tag at %p\n", data_tag);
ll_node *empty_node = __search_ll_node(ll_head, data);
empty_node->used = false;
// Free the node data_tag->prev->next = data_tag->next;
if (!empty_node->previous->used) { data_tag->next->prev = data_tag->prev;
empty_node->size += empty_node->previous->size;
empty_node->previous->previous->next = empty_node;
ll_node* previous = empty_node->previous;
empty_node->previous = empty_node->previous->previous;
free(previous);
}
if (!empty_node->next->used) {
empty_node->size += empty_node->next->size;
empty_node->next->next->previous = empty_node;
ll_node* next = empty_node->next;
empty_node->next = empty_node->next->next;
free(next);
}
} }
void print(ll_node *ll_head) { void print() {
printf("==== MEM DUMP ====\n"); printf("==== MEM DUMP ====\n");
ll_node *curr_node = ll_head; page_tag *curr_page = start;
while (curr_node != NULL) { int i = 0;
if (!curr_node->used) { while (curr_page != NULL) {
printf("empty"); printf("%d: [%p (%zu)] [%p (%zu)]\n",
} else { i,
printf("%p", curr_node->data); curr_page, sizeof(page_tag),
} curr_page + 1, curr_page->size);
printf(" (%d)\n", curr_node->size);
curr_node = curr_node->next; void *empty_start = (void *) curr_page + sizeof(page_tag) + curr_page->size;
if (empty_start + sizeof(page_tag) < (void *) curr_page->next) {
printf("empty_page (%ld, %ld)\n",
sizeof(page_tag),
(void *) curr_page->next -
(empty_start + sizeof(page_tag)));
} else if (empty_start < (void *) curr_page->next) {
printf("not enough room (%ld)\n",
(void *) curr_page->next - empty_start);
}
curr_page = curr_page->next;
i++;
} }
printf("-------------------\n\n"); printf("-------------------\n\n");
} }
void test_allocs(){ void test_allocs() {
ll_node *ll_head = __new_node(); void *ptr0 = __alloc(64);
ll_head->data = malloc(sizeof(size_t) * 1000); void *ptr1 = __alloc(64);
ll_head->used = true; void *ptr4 = __alloc(64);
ll_head->size = 1; print();
void* ptr0 = __alloc(ll_head, 5);
void* ptr1 = __alloc(ll_head, 5);
void* ptr4 = __alloc(ll_head, 5);
print(ll_head);
printf("Free nr 3\n"); printf("Free nr 2 -> %p\n", ptr1);
__free(ll_head, ptr1); __free(ptr1);
print(ll_head); print();
printf("Alloc 3 bytes\n"); printf("Alloc 32 bytes\n");
void* ptr2 = __alloc(ll_head, 3); void *ptr2 = __alloc(32);
print(ll_head); print();
printf("Alloc 3 bytes\n"); printf("Alloc 32 bytes\n");
__alloc(ll_head, 3); __alloc(32);
print(ll_head); print();
printf("Alloc 2 bytes\n"); printf("Alloc 8 bytes\n");
void* ptr3 = __alloc(ll_head, 2); void *ptr3 = __alloc(8);
print(ll_head); print();
__free(ptr2);
print();
__free(ptr4);
print();
__free(ptr3);
print();
__free(ptr0);
print();
printf("#########\nTry almost fill\n");
__alloc(160);
print();
__alloc(50);
print();
__free(ll_head, ptr2);
print(ll_head);
__free(ll_head, ptr4);
print(ll_head);
__free(ll_head, ptr3);
print(ll_head);
__free(ll_head, ptr0);
print(ll_head);
} }
int main() { int main() {
start = malloc(sizeof(size_t) * 1000);
start->next = NULL;
start->prev = NULL;
test_allocs(); test_allocs();
} }