use typedef for free_block
This commit is contained in:
@ -34,9 +34,9 @@ void LinkedListAllocator::init() {
|
|||||||
|
|
||||||
/* Hier muess Code eingefuegt werden */
|
/* Hier muess Code eingefuegt werden */
|
||||||
|
|
||||||
this->free_start = (struct free_block*)this->heap_start;
|
this->free_start = (free_block*)this->heap_start;
|
||||||
this->free_start->allocated = false;
|
this->free_start->allocated = false;
|
||||||
this->free_start->size = this->heap_size - sizeof(struct free_block);
|
this->free_start->size = this->heap_size - sizeof(free_block);
|
||||||
this->free_start->next = this->free_start; // Only one block, points to itself
|
this->free_start->next = this->free_start; // Only one block, points to itself
|
||||||
|
|
||||||
kout << "Initialized LinkedList Allocator" << endl
|
kout << "Initialized LinkedList Allocator" << endl
|
||||||
@ -62,7 +62,7 @@ void LinkedListAllocator::dump_free_memory() {
|
|||||||
} else {
|
} else {
|
||||||
kout << " - Freelist start: " << hex << (unsigned int)this->free_start << endl;
|
kout << " - Freelist start: " << hex << (unsigned int)this->free_start << endl;
|
||||||
|
|
||||||
struct free_block* current = this->free_start;
|
free_block* current = this->free_start;
|
||||||
do {
|
do {
|
||||||
kout << " - Free Block (Start: " << hex << (unsigned int)current
|
kout << " - Free Block (Start: " << hex << (unsigned int)current
|
||||||
<< " Size: " << hex << current->size << ")" << endl;
|
<< " Size: " << hex << current->size << ")" << endl;
|
||||||
@ -95,27 +95,27 @@ void* LinkedListAllocator::alloc(unsigned int req_size) {
|
|||||||
kout << " - Rounded to word border (+" << dec << req_size_diff << " bytes)" << endl;
|
kout << " - Rounded to word border (+" << dec << req_size_diff << " bytes)" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct free_block* current = this->free_start;
|
free_block* current = this->free_start;
|
||||||
do {
|
do {
|
||||||
if (current->size >= rreq_size) {
|
if (current->size >= rreq_size) {
|
||||||
// Current block large enough
|
// Current block large enough
|
||||||
// We now have: [<> | current | <>]
|
// We now have: [<> | current | <>]
|
||||||
|
|
||||||
// Don't subtract to prevent underflow
|
// Don't subtract to prevent underflow
|
||||||
if (current->size >= rreq_size + sizeof(struct free_block) + HEAP_MIN_FREE_BLOCK_SIZE) {
|
if (current->size >= rreq_size + sizeof(free_block) + HEAP_MIN_FREE_BLOCK_SIZE) {
|
||||||
// Block so large it can be cut
|
// Block so large it can be cut
|
||||||
|
|
||||||
// Create new header after allocated memory and rearrange pointers
|
// Create new header after allocated memory and rearrange pointers
|
||||||
// [<> | current | new_next | <>]
|
// [<> | current | new_next | <>]
|
||||||
// In case of only one freeblock:
|
// In case of only one freeblock:
|
||||||
// [current | new_next]
|
// [current | new_next]
|
||||||
struct free_block* new_next =
|
free_block* new_next =
|
||||||
(struct free_block*)((unsigned int)current + sizeof(struct free_block) + rreq_size);
|
(free_block*)((unsigned int)current + sizeof(free_block) + rreq_size);
|
||||||
|
|
||||||
// If only one block exists, current->next is current
|
// If only one block exists, current->next is current
|
||||||
// This shouldn't be a problem since the block gets removed from the list later
|
// This shouldn't be a problem since the block gets removed from the list later
|
||||||
new_next->next = current->next;
|
new_next->next = current->next;
|
||||||
new_next->size = current->size - (rreq_size + sizeof(struct free_block));
|
new_next->size = current->size - (rreq_size + sizeof(free_block));
|
||||||
|
|
||||||
current->next = new_next; // We want to reach the next free block from the allocated block
|
current->next = new_next; // We want to reach the next free block from the allocated block
|
||||||
current->size = rreq_size;
|
current->size = rreq_size;
|
||||||
@ -139,14 +139,14 @@ void* LinkedListAllocator::alloc(unsigned int req_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Block aushängen
|
// Block aushängen
|
||||||
struct free_block* previous = this->find_previous_block(current);
|
free_block* previous = this->find_previous_block(current);
|
||||||
previous->next = current->next;
|
previous->next = current->next;
|
||||||
current->allocated = true;
|
current->allocated = true;
|
||||||
|
|
||||||
// We leave the current->next pointer intact although the block is allocated
|
// We leave the current->next pointer intact although the block is allocated
|
||||||
// to allow easier merging of adjacent free blocks
|
// to allow easier merging of adjacent free blocks
|
||||||
|
|
||||||
return (void*)((unsigned int)current + sizeof(struct free_block)); // Speicheranfang, nicht header
|
return (void*)((unsigned int)current + sizeof(free_block)); // Speicheranfang, nicht header
|
||||||
}
|
}
|
||||||
|
|
||||||
current = current->next;
|
current = current->next;
|
||||||
@ -167,7 +167,7 @@ void LinkedListAllocator::free(void* ptr) {
|
|||||||
|
|
||||||
kout << "Freeing " << hex << (unsigned int)ptr << endl;
|
kout << "Freeing " << hex << (unsigned int)ptr << endl;
|
||||||
|
|
||||||
struct free_block* block_start = (struct free_block*)((unsigned int)ptr - sizeof(struct free_block));
|
free_block* block_start = (free_block*)((unsigned int)ptr - sizeof(free_block));
|
||||||
|
|
||||||
// Reenable the freelist if no block was available
|
// Reenable the freelist if no block was available
|
||||||
// This also means that no merging can be done
|
// This also means that no merging can be done
|
||||||
@ -181,18 +181,18 @@ void LinkedListAllocator::free(void* ptr) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct free_block* next_block =
|
free_block* next_block =
|
||||||
(struct free_block*)((unsigned int)block_start + sizeof(struct free_block) + block_start->size);
|
(free_block*)((unsigned int)block_start + sizeof(free_block) + block_start->size);
|
||||||
|
|
||||||
// Find the next free block, multiple next blocks can be allocated so walk through them
|
// Find the next free block, multiple next blocks can be allocated so walk through them
|
||||||
struct free_block* next_free = block_start->next;
|
free_block* next_free = block_start->next;
|
||||||
while (next_free->allocated) {
|
while (next_free->allocated) {
|
||||||
next_free = next_free->next;
|
next_free = next_free->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct free_block* previous_free = this->find_previous_block(next_free);
|
free_block* previous_free = this->find_previous_block(next_free);
|
||||||
struct free_block* previous_free_next =
|
free_block* previous_free_next =
|
||||||
(struct free_block*)((unsigned int)previous_free + sizeof(struct free_block) + previous_free->size);
|
(free_block*)((unsigned int)previous_free + sizeof(free_block) + previous_free->size);
|
||||||
|
|
||||||
// We have: [previous_free | previous_free_next | <> | block_start | next_block | <> | next_free]
|
// We have: [previous_free | previous_free_next | <> | block_start | next_block | <> | next_free]
|
||||||
// The <> spaces don't have to exist and next_block could be the same as next_free
|
// The <> spaces don't have to exist and next_block could be the same as next_free
|
||||||
@ -217,7 +217,7 @@ void LinkedListAllocator::free(void* ptr) {
|
|||||||
// If next_free is the only free block it points to itself, so fix that
|
// If next_free is the only free block it points to itself, so fix that
|
||||||
block_start->next = block_start;
|
block_start->next = block_start;
|
||||||
}
|
}
|
||||||
block_start->size = block_start->size + sizeof(struct free_block) + next_free->size;
|
block_start->size = block_start->size + sizeof(free_block) + next_free->size;
|
||||||
|
|
||||||
// There shouldn't exist any other allocated blocks pointing to next_free,
|
// There shouldn't exist any other allocated blocks pointing to next_free,
|
||||||
// the current one should be the only one (or else I have done something wrong)
|
// the current one should be the only one (or else I have done something wrong)
|
||||||
@ -248,7 +248,7 @@ void LinkedListAllocator::free(void* ptr) {
|
|||||||
// [previous_free | block_start]
|
// [previous_free | block_start]
|
||||||
|
|
||||||
previous_free->next = block_start->next;
|
previous_free->next = block_start->next;
|
||||||
previous_free->size = previous_free->size + sizeof(struct free_block) + block_start->size;
|
previous_free->size = previous_free->size + sizeof(free_block) + block_start->size;
|
||||||
|
|
||||||
// For pointers to block_start the same as above applies
|
// For pointers to block_start the same as above applies
|
||||||
// so I don't think I have to manage anything else here
|
// so I don't think I have to manage anything else here
|
||||||
@ -265,9 +265,9 @@ void LinkedListAllocator::free(void* ptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: I added this
|
// NOTE: I added this
|
||||||
struct free_block* LinkedListAllocator::find_previous_block(struct free_block* next_block) {
|
free_block* LinkedListAllocator::find_previous_block(free_block* next_block) {
|
||||||
// Durchlaufe die ganze freispeicherliste bis zum Block der auf next_block zeigt
|
// Durchlaufe die ganze freispeicherliste bis zum Block der auf next_block zeigt
|
||||||
struct free_block* current = next_block;
|
free_block* current = next_block;
|
||||||
while (current->next != next_block) {
|
while (current->next != next_block) {
|
||||||
// NOTE: This will get stuck if called on the wrong block
|
// NOTE: This will get stuck if called on the wrong block
|
||||||
current = current->next;
|
current = current->next;
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
#include "kernel/Allocator.h"
|
#include "kernel/Allocator.h"
|
||||||
|
|
||||||
// Format eines freien Blocks, 4 + 4 + 4 Byte
|
// Format eines freien Blocks, 4 + 4 + 4 Byte
|
||||||
struct free_block {
|
typedef struct free_block {
|
||||||
bool allocated; // NOTE: I added this to allow easier merging of free blocks:
|
bool allocated; // NOTE: I added this to allow easier merging of free blocks:
|
||||||
// When freeing an allocated block, its next-pointer can
|
// When freeing an allocated block, its next-pointer can
|
||||||
// point to another allocated block, the next free block
|
// point to another allocated block, the next free block
|
||||||
@ -25,7 +25,7 @@ struct free_block {
|
|||||||
// to merge blocks. Would be faster with doubly linked list.
|
// to merge blocks. Would be faster with doubly linked list.
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
struct free_block* next;
|
struct free_block* next;
|
||||||
};
|
} free_block;
|
||||||
|
|
||||||
class LinkedListAllocator : Allocator {
|
class LinkedListAllocator : Allocator {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user