Use padding to cleanup code

This commit is contained in:
Baptiste Wicht 2014-02-03 14:31:01 +01:00
parent 96221553dd
commit c7f4bdffb3

View File

@ -28,67 +28,49 @@ private:
size_t __size; size_t __size;
malloc_header_chunk* __next; malloc_header_chunk* __next;
malloc_header_chunk* __prev; malloc_header_chunk* __prev;
size_t pad; uint32_t _free;
uint16_t left;
uint16_t right;
public: public:
size_t size() const { size_t& size(){
return __size & ~0x3;
}
size_t& size_ref(){
return __size; return __size;
} }
bool has_left() const { bool has_left() const {
return __size & 0x1; return left;
} }
bool has_right() const { bool has_right() const {
return __size & 0x2; return right;
} }
void set_left(bool left){ void set_left(bool left){
if(left){ this->left = left;
__size = __size | 0x1;
} else {
__size = __size & ~0x1;
}
} }
void set_right(bool right){ void set_right(bool right){
if(right){ this->right = right;
__size = __size | 0x2;
} else {
__size = __size & ~0x2;
}
} }
constexpr malloc_header_chunk* next() const { malloc_header_chunk*& next(){
return __next; return __next;
} }
malloc_header_chunk*& next_ref(){ malloc_header_chunk*& prev(){
return __next;
}
constexpr malloc_header_chunk* prev() const {
return reinterpret_cast<malloc_header_chunk*>(reinterpret_cast<uintptr_t>(__prev) & (~0l - 1));
}
malloc_header_chunk*& prev_ref(){
return __prev; return __prev;
} }
void set_free(){ void set_free(){
__prev = reinterpret_cast<malloc_header_chunk*>(reinterpret_cast<uintptr_t>(__prev) | 0x1); _free = 1;
} }
void set_not_free(){ void set_not_free(){
__prev = reinterpret_cast<malloc_header_chunk*>(reinterpret_cast<uintptr_t>(__prev) & (~0l - 1)); _free = 0;
} }
bool is_free() const { bool is_free() const {
return reinterpret_cast<uintptr_t>(__prev) & 0x1; return _free;
} }
constexpr malloc_footer_chunk* footer() const { constexpr malloc_footer_chunk* footer() const {
@ -102,11 +84,7 @@ private:
uint64_t __size; uint64_t __size;
public: public:
size_t size() const { size_t& size(){
return __size;
}
size_t& size_ref(){
return __size; return __size;
} }
}; };
@ -192,27 +170,30 @@ void debug_malloc(const char* point = nullptr){
//Insert new_block after current in the free list and update //Insert new_block after current in the free list and update
//all the necessary links //all the necessary links
void insert_after(malloc_header_chunk* current, malloc_header_chunk* new_block){ void insert_after(malloc_header_chunk* current, malloc_header_chunk* new_block){
new_block->next_ref() = current->next(); //Link the new block to its surroundings
new_block->prev_ref() = current; new_block->next() = current->next();
new_block->set_free(); new_block->prev() = current;
current->next()->prev_ref() = new_block; //Link surroundings to the new block
current->next()->set_free(); current->next()->prev() = new_block;
current->next_ref() = new_block; current->next() = new_block;
new_block->set_free();
} }
//Remove the given block from the free list //Remove the given block from the free list
//The node is directly marked as not free //The node is directly marked as not free
void remove(malloc_header_chunk* current){ void remove(malloc_header_chunk* current){
current->prev()->next_ref() = current->next(); //Unlink the node
current->next()->prev_ref() = current->prev(); current->prev()->next() = current->next();
current->next()->set_free(); current->next()->prev() = current->prev();
//Make sure the node is clean //Make sure the node is clean
current->prev_ref() = nullptr; current->prev() = nullptr;
current->next_ref() = nullptr; current->next() = nullptr;
//No need to unmark the free bit here as we set current->next to zero //The node is not free anymore
current->set_not_free();
} }
void init_head(){ void init_head(){
@ -222,8 +203,8 @@ void init_head(){
head.size_2 = 0; head.size_2 = 0;
malloc_head = reinterpret_cast<malloc_header_chunk*>(&head); malloc_head = reinterpret_cast<malloc_header_chunk*>(&head);
malloc_head->next_ref() = malloc_head; malloc_head->next() = malloc_head;
malloc_head->prev_ref() = malloc_head; malloc_head->prev() = malloc_head;
malloc_head->set_left(false); malloc_head->set_left(false);
malloc_head->set_right(false); malloc_head->set_right(false);
} }
@ -246,8 +227,8 @@ void expand_heap(malloc_header_chunk* current, size_t bytes = 0){
auto header = reinterpret_cast<malloc_header_chunk*>(block); auto header = reinterpret_cast<malloc_header_chunk*>(block);
//Update the sizes //Update the sizes
header->size_ref() = blocks * BLOCK_SIZE - META_SIZE; header->size() = blocks * BLOCK_SIZE - META_SIZE;
header->footer()->size_ref() = header->size(); header->footer()->size() = header->size();
//When created a block has no left and right neighbour //When created a block has no left and right neighbour
header->set_left(false); header->set_left(false);
@ -299,8 +280,8 @@ malloc_header_chunk* coalesce(malloc_header_chunk* b){
b = a; b = a;
b->size_ref() = new_size; b->size() = new_size;
b->footer()->size_ref() = new_size; b->footer()->size() = new_size;
b->set_left(block_left); b->set_left(block_left);
b->set_right(block_right); b->set_right(block_right);
@ -315,8 +296,8 @@ malloc_header_chunk* coalesce(malloc_header_chunk* b){
//Remove c from the free list //Remove c from the free list
remove(c); remove(c);
b->size_ref() = new_size; b->size() = new_size;
b->footer()->size_ref() = new_size; b->footer()->size() = new_size;
b->set_left(block_left); b->set_left(block_left);
b->set_right(block_right); b->set_right(block_right);
@ -368,8 +349,8 @@ void* malloc::k_malloc(uint64_t bytes){
auto block_right = current->has_right(); auto block_right = current->has_right();
//Set the new size of the current block //Set the new size of the current block
current->size_ref() = bytes; current->size() = bytes;
current->footer()->size_ref() = bytes; current->footer()->size() = bytes;
current->set_left(block_left); current->set_left(block_left);
current->set_right(true); current->set_right(true);
@ -379,8 +360,8 @@ void* malloc::k_malloc(uint64_t bytes){
reinterpret_cast<uintptr_t>(current) + bytes + META_SIZE); reinterpret_cast<uintptr_t>(current) + bytes + META_SIZE);
//Update the size of the new block //Update the size of the new block
new_block->size_ref() = new_block_size; new_block->size() = new_block_size;
new_block->footer()->size_ref() = new_block->size(); new_block->footer()->size() = new_block->size();
new_block->set_left(true); new_block->set_left(true);
new_block->set_right(block_right); new_block->set_right(block_right);