Refactor to holding linked list data before the alloced blocks.
These "tags" hold the pointers between the alloced blocks.
This commit is contained in:
parent
ea9f4c6e49
commit
fafe06ed2b
2 changed files with 102 additions and 118 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
|
||||||
|
page_tag *__searchPage(void *data) {
|
||||||
|
page_tag *curr_page = start;
|
||||||
|
while (curr_page + (sizeof(page_tag)) != data) {
|
||||||
|
curr_page = curr_page->next;
|
||||||
|
}
|
||||||
|
return curr_page;
|
||||||
}
|
}
|
||||||
|
|
||||||
ll_node *__search_ll_node(ll_node *heap_head, void *data) {
|
///**
|
||||||
ll_node *curr_node = heap_head;
|
// * @param alignment
|
||||||
while (!curr_node->used || curr_node->data != data) {
|
// * @param size
|
||||||
curr_node = curr_node->next;
|
// * @return A block aligned with the alignment parameter.
|
||||||
|
// */
|
||||||
|
//void* aligned_alloc(int alignment, int size){
|
||||||
|
// // TODO
|
||||||
|
// return NULL;
|
||||||
|
//}
|
||||||
|
|
||||||
|
void *__alloc(size_t size) {
|
||||||
|
page_tag *curr_page = start;
|
||||||
|
|
||||||
|
while (curr_page->next != NULL) {
|
||||||
|
page_tag *new_page = ((void *) curr_page) + sizeof(page_tag) + curr_page->size;
|
||||||
|
if ((void *) new_page + sizeof(page_tag) + size <= curr_page->next) {
|
||||||
|
|
||||||
|
new_page->size = size;
|
||||||
|
|
||||||
|
curr_page->next->prev = new_page;
|
||||||
|
new_page->next = curr_page->next;
|
||||||
|
|
||||||
|
curr_page->next = new_page;
|
||||||
|
new_page->prev = curr_page;
|
||||||
|
|
||||||
|
return new_page + 1;
|
||||||
}
|
}
|
||||||
return curr_node;
|
curr_page = curr_page->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
page_tag *new_page = ((void *) curr_page) + sizeof(page_tag) + curr_page->size;
|
||||||
|
new_page->size = size;
|
||||||
|
|
||||||
|
curr_page->next = new_page;
|
||||||
|
new_page->prev = curr_page;
|
||||||
|
return new_page + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *__alloc(ll_node *ll_head, int size) {
|
void __free(void *data) {
|
||||||
ll_node *curr_node = ll_head;
|
page_tag *data_tag = data - sizeof(page_tag);
|
||||||
ll_node *new_node = __new_node();
|
printf("found tag at %p\n", data_tag);
|
||||||
new_node->used = true;
|
|
||||||
new_node->size = size;
|
|
||||||
|
|
||||||
while (curr_node->next != NULL) {
|
data_tag->prev->next = data_tag->next;
|
||||||
curr_node = curr_node->next;
|
data_tag->next->prev = data_tag->prev;
|
||||||
|
|
||||||
if (!curr_node->used && curr_node->size >= size) {
|
|
||||||
curr_node->size -= size;
|
|
||||||
|
|
||||||
// xxx -> <new_node> -> empty block -> yyy
|
|
||||||
|
|
||||||
// link new_node to xxx
|
|
||||||
curr_node->previous->next = new_node;
|
|
||||||
new_node->previous = curr_node->previous;
|
|
||||||
|
|
||||||
// link new_node to empty_block or yyy
|
|
||||||
if (curr_node->size == 0) {
|
|
||||||
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;
|
|
||||||
new_node->data = data;
|
|
||||||
return new_node->data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
new_node->previous = curr_node;
|
|
||||||
curr_node->next = new_node;
|
|
||||||
|
|
||||||
void *data = new_node->previous->data + new_node->previous->size;
|
|
||||||
new_node->data = data;
|
|
||||||
return new_node->data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void __free(ll_node *ll_head, void *data) {
|
void print() {
|
||||||
// Search the corresponding block of memory
|
|
||||||
// TODO This can be held in a table for quicker lookup
|
|
||||||
ll_node *empty_node = __search_ll_node(ll_head, data);
|
|
||||||
empty_node->used = false;
|
|
||||||
|
|
||||||
// Free the node
|
|
||||||
if (!empty_node->previous->used) {
|
|
||||||
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) {
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue