aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src/memory/heap
diff options
context:
space:
mode:
authorMatteo Gmür <matteo.gmuer1@ost.ch>2025-05-11 08:48:57 +0000
committerMatteo Gmür <matteo.gmuer1@ost.ch>2025-05-11 08:48:57 +0000
commit833cd6446d9981a262959749c0e248e33b54c174 (patch)
tree4378760ddf5d6034d2c702274a6757940e7afe44 /arch/x86_64/src/memory/heap
parent955ab48fe6329b2cbc8c5855a8ba7290185d0ea3 (diff)
downloadteachos-833cd6446d9981a262959749c0e248e33b54c174.tar.xz
teachos-833cd6446d9981a262959749c0e248e33b54c174.zip
Adjust user heap allocator with expanding heap functionality
Diffstat (limited to 'arch/x86_64/src/memory/heap')
-rw-r--r--arch/x86_64/src/memory/heap/user_heap_allocator.cpp41
1 files changed, 40 insertions, 1 deletions
diff --git a/arch/x86_64/src/memory/heap/user_heap_allocator.cpp b/arch/x86_64/src/memory/heap/user_heap_allocator.cpp
index 6843d66..ce8b0fa 100644
--- a/arch/x86_64/src/memory/heap/user_heap_allocator.cpp
+++ b/arch/x86_64/src/memory/heap/user_heap_allocator.cpp
@@ -1,5 +1,6 @@
#include "arch/memory/heap/user_heap_allocator.hpp"
+#include "arch/context_switching/syscall/main.hpp"
#include "arch/exception_handling/assert.hpp"
#include "arch/exception_handling/panic.hpp"
@@ -18,7 +19,7 @@ namespace teachos::arch::memory::heap
heap_size > min_allocatable_size(),
"[Linked List Allocator] Total heap size can not be smaller than minimum of 16 bytes to hold "
"atleast one memory hole entry");
- first = new (reinterpret_cast<void *>(heap_start)) memory_block(heap_size, nullptr);
+ // first = new (reinterpret_cast<void *>(heap_start)) memory_block(heap_size, nullptr);
}
auto user_heap_allocator::allocate(std::size_t size) -> void *
@@ -57,6 +58,30 @@ namespace teachos::arch::memory::heap
current = current->next;
}
+ current = expand_heap_if_full();
+
+ if (current != nullptr)
+ {
+ if (current->size == total_size)
+ {
+ auto const memory_address = remove_free_memory_block(previous, current);
+ new (memory_address) std::size_t(total_size);
+ mutex.unlock();
+ return reinterpret_cast<void *>(reinterpret_cast<std::size_t>(memory_address) + sizeof(std::size_t));
+ }
+ else if (current->size >= total_size + min_allocatable_size())
+ {
+ // Ensure that the allocated size block is atleast 16 bytes (required because if we free the hole afterwards
+ // there needs to be enough space for a memory block). Therefore we allocate more than is actually required if
+ // the total size was less and simply deallocate it as well
+ auto const max_size = std::max(total_size, min_allocatable_size());
+ auto const memory_address = split_free_memory_block(previous, current, max_size);
+ new (memory_address) std::size_t(max_size);
+ mutex.unlock();
+ return reinterpret_cast<void *>(reinterpret_cast<std::size_t>(memory_address) + sizeof(std::size_t));
+ }
+ }
+
exception_handling::panic("[Linked List Allocator] Out of memory");
}
@@ -91,6 +116,20 @@ namespace teachos::arch::memory::heap
mutex.unlock();
}
+ auto user_heap_allocator::expand_heap_if_full() -> memory_block *
+ {
+ context_switching::syscall::arguments args{};
+ auto const result = context_switching::syscall::syscall(context_switching::syscall::type::EXPAND_HEAP, args);
+
+ if (!result.error_code)
+ {
+ uint64_t const heap_start = result.values.arg_0;
+ uint64_t const heap_size = result.values.arg_1;
+ return new (reinterpret_cast<void *>(heap_start)) memory_block(heap_size, nullptr);
+ }
+ return nullptr;
+ }
+
auto user_heap_allocator::remove_free_memory_block(memory_block * previous_block, memory_block * current_block)
-> void *
{