aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src/memory
diff options
context:
space:
mode:
authorFabian Imhof <fabian.imhof@ost.ch>2024-12-01 11:44:30 +0000
committerFabian Imhof <fabian.imhof@ost.ch>2024-12-01 11:44:30 +0000
commitb8fd52b6b3a7f002cff58ff8da0313a684cb3ab4 (patch)
tree1c6b91cb81085edc073b1f84910acd6f23ae1c2d /arch/x86_64/src/memory
parenteba6c94eed15b90ea8a09e4bc16ae1c0f1645dea (diff)
downloadteachos-b8fd52b6b3a7f002cff58ff8da0313a684cb3ab4.tar.xz
teachos-b8fd52b6b3a7f002cff58ff8da0313a684cb3ab4.zip
implement heap linked_list deallocate
Diffstat (limited to 'arch/x86_64/src/memory')
-rw-r--r--arch/x86_64/src/memory/heap/linked_list_allocator.cpp64
1 files changed, 43 insertions, 21 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 9b27f70..3330399 100644
--- a/arch/x86_64/src/memory/heap/linked_list_allocator.cpp
+++ b/arch/x86_64/src/memory/heap/linked_list_allocator.cpp
@@ -60,43 +60,65 @@ namespace teachos::arch::memory::heap
exception_handling::assert(size < min_allocatable_size(),
"[Linked List Allocator] Allocated memory cannot be smaller than 16 bytes");
+ auto const start_address = reinterpret_cast<std::size_t>(pointer);
+ auto const end_address = start_address + size;
+
auto & previous = first;
auto & current = first;
while (current != nullptr)
{
- // if pointer + size < current
- // create memory block
- auto const previous_address = reinterpret_cast<std::size_t>(pointer);
- auto const new_address = previous_address + size;
-
- if (new_address != reinterpret_cast<std::size_t>(current) &&
- previous_address != (reinterpret_cast<std::size_t>(previous) + previous->size))
+ if (reinterpret_cast<std::size_t>(current) >= end_address)
{
- auto new_block = new (pointer) memory_block(size, current);
- previous->next = new_block;
- return;
+ break;
}
- // elseif pointer + size == current
- // combine memory block with current
- // combine(previous, pointer, current)
-
- previous = current;
+ previous->next = current;
current = current->next;
}
+
+ coalesce_free_memory_block(previous, current, pointer, size);
}
auto linked_list_allocator::split_free_memory_block(memory_block *& current_block, std::size_t size) -> void *
{
- auto const previous_address = reinterpret_cast<std::size_t>(current_block);
- auto const new_address = previous_address + size;
+ auto const start_address = reinterpret_cast<std::size_t>(current_block);
+ auto const end_address = start_address + size;
current_block =
- new (reinterpret_cast<void *>(new_address)) memory_block(current_block->size - size, current_block->next);
- return reinterpret_cast<void *>(previous_address);
+ new (reinterpret_cast<void *>(end_address)) memory_block(current_block->size - size, current_block->next);
+ return reinterpret_cast<void *>(start_address);
}
- // auto linked_list_allocator::combine_free_memory_block(memory_block *& previous_block, memory_block *&
- // current_block, std::size_t size) -> void *
+ auto linked_list_allocator::coalesce_free_memory_block(memory_block *& previous_block, memory_block *& current_block,
+ void * pointer, std::size_t size) -> void *
+ {
+ auto const start_address = reinterpret_cast<std::size_t>(pointer);
+ auto const end_address = start_address + size;
+
+ auto block_size = size;
+ auto new_block_address = pointer;
+ auto next_block = current_block;
+
+ // If free memory block after block to deallocate is adjacent
+ if (end_address == reinterpret_cast<std::size_t>(current_block))
+ {
+ block_size += current_block->size;
+ next_block = current_block->next;
+
+ delete current_block;
+ }
+
+ // If free memory block before block to deallocate is adjacent
+ if (start_address == (reinterpret_cast<std::size_t>(previous_block) + previous_block->size))
+ {
+ block_size += previous_block->size;
+
+ previous_block->size = block_size;
+ previous_block->next = next_block;
+ return;
+ }
+
+ new (reinterpret_cast<void *>(new_block_address)) memory_block(block_size, next_block);
+ }
} // namespace teachos::arch::memory::heap