aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src/memory
diff options
context:
space:
mode:
authorMatteo Gmür <matteo.gmuer1@ost.ch>2024-12-01 12:38:38 +0000
committerMatteo Gmür <matteo.gmuer1@ost.ch>2024-12-01 12:38:38 +0000
commit0cf972394e99dfa69fbaf2ec9f4c718fd36bbc3e (patch)
tree5f3270e31d2e61cacd4f018cfb2ae0765176a60a /arch/x86_64/src/memory
parent2671b9522db44418536559524a22c95d3575569e (diff)
downloadteachos-0cf972394e99dfa69fbaf2ec9f4c718fd36bbc3e.tar.xz
teachos-0cf972394e99dfa69fbaf2ec9f4c718fd36bbc3e.zip
Add comments and fix edge case
Diffstat (limited to 'arch/x86_64/src/memory')
-rw-r--r--arch/x86_64/src/memory/heap/linked_list_allocator.cpp23
1 files changed, 20 insertions, 3 deletions
diff --git a/arch/x86_64/src/memory/heap/linked_list_allocator.cpp b/arch/x86_64/src/memory/heap/linked_list_allocator.cpp
index 98a936c..63a762e 100644
--- a/arch/x86_64/src/memory/heap/linked_list_allocator.cpp
+++ b/arch/x86_64/src/memory/heap/linked_list_allocator.cpp
@@ -68,6 +68,8 @@ namespace teachos::arch::memory::heap
while (current != nullptr)
{
+ // Current address of the free memory block now points to an address that is after our block to deallocate in heap
+ // memory space.
if (reinterpret_cast<std::size_t>(current) >= end_address)
{
break;
@@ -95,10 +97,22 @@ namespace teachos::arch::memory::heap
auto const start_address = reinterpret_cast<std::size_t>(pointer);
auto const end_address = start_address + size;
+ // Inital values if there are no adjacent blocks either before or after, meaning we have to simply create a free
+ // memory block that is placed in between the previous and next block.
auto block_size = size;
auto next_block = current_block;
- // If free memory block after block to deallocate is adjacent
+ // Heap memory has been completly used up and therefore the inital free pointer is null and this deallocation will
+ // result in the first inital pointer in our linked list of free memory blocks.
+ if (previous_block == nullptr)
+ {
+ previous_block = new (pointer) memory_block(block_size, next_block);
+ return;
+ }
+
+ // If the block we want to deallocate is before another free block and we can therefore combine both into one.
+ // This is done by deleting the current free block and creating a new block at the start address of the block to
+ // deallocate with both the size of the block to deallcoate and the free block next to it.
if (end_address == reinterpret_cast<std::size_t>(current_block))
{
block_size += current_block->size;
@@ -107,7 +121,9 @@ namespace teachos::arch::memory::heap
delete current_block;
}
- // If free memory block before block to deallocate is adjacent
+ // If the block we want to deallocate is behind another free block and we can therefore combine both into one.
+ // This is done by simply changin the size of the previous block to include the size of the block to deallocate.
+ // This is done, because the previous block might still be referencered by the next field of other memory blocks.
if (start_address == (reinterpret_cast<std::size_t>(previous_block) + previous_block->size))
{
block_size += previous_block->size;
@@ -117,7 +133,8 @@ namespace teachos::arch::memory::heap
return;
}
- new (reinterpret_cast<void *>(pointer)) memory_block(block_size, next_block);
+ auto const new_block = new (pointer) memory_block(block_size, next_block);
+ previous_block->next = new_block;
}
} // namespace teachos::arch::memory::heap