aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src
diff options
context:
space:
mode:
authorFabian Imhof <fabian.imhof@ost.ch>2025-02-27 09:21:43 +0100
committerFabian Imhof <fabian.imhof@ost.ch>2025-02-27 09:21:43 +0100
commit3fb836101a2032e93f7b82c924ce208d7377a5ea (patch)
tree52f9aa1f5316b9938e74f43637c0641803fda01a /arch/x86_64/src
parentcd42c21f2460751428b3e1b4ae07ea0b924967bc (diff)
parent2f1f0fa8b0dc1893219be68ab8bf653b5d6349fb (diff)
downloadteachos-3fb836101a2032e93f7b82c924ce208d7377a5ea.tar.xz
teachos-3fb836101a2032e93f7b82c924ce208d7377a5ea.zip
Merge branch 'feat_new_delete_override' into 'develop_ba'
new delete override See merge request teachos/kernel!4
Diffstat (limited to 'arch/x86_64/src')
-rw-r--r--arch/x86_64/src/boot/boot.s2
-rw-r--r--arch/x86_64/src/kernel/main.cpp30
-rw-r--r--arch/x86_64/src/memory/cpu/control_register.cpp8
-rw-r--r--arch/x86_64/src/memory/heap/bump_allocator.cpp4
-rw-r--r--arch/x86_64/src/memory/heap/global_heap_allocator.cpp78
-rw-r--r--arch/x86_64/src/memory/heap/linked_list_allocator.cpp41
-rw-r--r--arch/x86_64/src/memory/main.cpp2
7 files changed, 122 insertions, 43 deletions
diff --git a/arch/x86_64/src/boot/boot.s b/arch/x86_64/src/boot/boot.s
index 8d27ea1..2197dce 100644
--- a/arch/x86_64/src/boot/boot.s
+++ b/arch/x86_64/src/boot/boot.s
@@ -197,8 +197,10 @@ _start:
call enable_paging
call enable_sse
+ cli // Clears the interrupt flag during the GDT setup
lgdt (global_descriptor_table_pointer)
jmp $global_descriptor_table_code,$_transition_to_long_mode
+ // The interrupt flag is set in cpp after setting up the GDT
call halt
diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp
index 681f960..472aed5 100644
--- a/arch/x86_64/src/kernel/main.cpp
+++ b/arch/x86_64/src/kernel/main.cpp
@@ -1,8 +1,7 @@
#include "arch/kernel/main.hpp"
#include "arch/memory/heap/bump_allocator.hpp"
-#include "arch/memory/heap/concept.hpp"
-#include "arch/memory/heap/linked_list_allocator.hpp"
+#include "arch/memory/heap/global_heap_allocator.hpp"
#include "arch/memory/main.hpp"
#include "arch/memory/multiboot/reader.hpp"
#include "arch/video/vga/text.hpp"
@@ -22,12 +21,8 @@ namespace teachos::arch::kernel
auto heap_test() -> void
{
- memory::heap::linked_list_allocator heap_allocator{memory::heap::HEAP_START,
- memory::heap::HEAP_START + memory::heap::HEAP_SIZE};
- auto test = heap_allocator.allocate(1024);
- auto test2 = new (test) memory::multiboot::memory_information{};
- auto test3 = new (static_cast<void *>(static_cast<memory::multiboot::memory_information *>(test) + 1))
- memory::multiboot::memory_information{};
+ auto test2 = new memory::multiboot::memory_information{};
+ auto test3 = new memory::multiboot::memory_information{};
auto test4 = *test2;
auto test5 = *test3;
test4.kernel_end = 5000;
@@ -42,18 +37,11 @@ namespace teachos::arch::kernel
test2->kernel_end = 2000;
test2->kernel_start = 1000;
test2->multiboot_start = 2000;
- heap_allocator.deallocate(test, 1024);
+ delete test2;
+ delete test3;
- auto test9 = heap_allocator.allocate(1024);
- auto test10 = heap_allocator.allocate(1024);
- auto test11 = heap_allocator.allocate(1024);
- heap_allocator.deallocate(test9, 1024);
- auto test12 = heap_allocator.allocate(1024);
- auto test13 = heap_allocator.allocate(1024);
- heap_allocator.deallocate(test11, 1024);
- heap_allocator.deallocate(test10, 1024);
- heap_allocator.deallocate(test13, 1024);
- heap_allocator.deallocate(test12, 1024);
+ auto test9 = new int(50);
+ delete test9;
}
auto main() -> void
@@ -64,8 +52,10 @@ namespace teachos::arch::kernel
video::vga::text::newline();
memory::initialize_memory_management();
-
// stack_overflow_test(0);
+
+ memory::heap::global_heap_allocator::register_heap_allocator(memory::heap::heap_allocator_type::LINKED_LIST);
+
heap_test();
}
} // namespace teachos::arch::kernel
diff --git a/arch/x86_64/src/memory/cpu/control_register.cpp b/arch/x86_64/src/memory/cpu/control_register.cpp
index 298874f..7ee88b5 100644
--- a/arch/x86_64/src/memory/cpu/control_register.cpp
+++ b/arch/x86_64/src/memory/cpu/control_register.cpp
@@ -1,6 +1,6 @@
#include "arch/memory/cpu/control_register.hpp"
-#include "arch/exception_handling/assert.hpp"
+#include "arch/exception_handling/panic.hpp"
#include <type_traits>
@@ -24,8 +24,7 @@ namespace teachos::arch::memory::cpu
asm volatile("mov %%cr4, %[output]" : [output] "=r"(current_value));
break;
default:
- exception_handling::assert(false,
- "[Control Register] Attempted to read non-existent or reserved control register");
+ exception_handling::panic("[Control Register] Attempted to read non-existent or reserved control register");
break;
}
return current_value;
@@ -60,8 +59,7 @@ namespace teachos::arch::memory::cpu
: "memory");
break;
default:
- exception_handling::assert(false,
- "[Control Register] Attempted to write non-existent or reserved control register");
+ exception_handling::panic("[Control Register] Attempted to write non-existent or reserved control register");
break;
}
}
diff --git a/arch/x86_64/src/memory/heap/bump_allocator.cpp b/arch/x86_64/src/memory/heap/bump_allocator.cpp
index bbf2021..df95346 100644
--- a/arch/x86_64/src/memory/heap/bump_allocator.cpp
+++ b/arch/x86_64/src/memory/heap/bump_allocator.cpp
@@ -42,9 +42,9 @@ namespace teachos::arch::memory::heap
}
}
- auto bump_allocator::deallocate(void * pointer, std::size_t size) -> void
+ auto bump_allocator::deallocate(void * pointer) noexcept -> void
{
- if (pointer || size)
+ if (pointer)
{
}
}
diff --git a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp
new file mode 100644
index 0000000..c1ca160
--- /dev/null
+++ b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp
@@ -0,0 +1,78 @@
+#include "arch/memory/heap/global_heap_allocator.hpp"
+
+#include "arch/exception_handling/assert.hpp"
+#include "arch/memory/heap/bump_allocator.hpp"
+#include "arch/memory/heap/linked_list_allocator.hpp"
+
+namespace teachos::arch::memory::heap
+{
+ heap_allocator * global_heap_allocator::allocator_instance = nullptr;
+
+ auto global_heap_allocator::allocate(std::size_t size) -> void * { return get().allocate(size); }
+
+ auto global_heap_allocator::deallocate(void * pointer) noexcept -> void { get().deallocate(pointer); }
+
+ auto global_heap_allocator::register_heap_allocator(heap_allocator_type new_type) -> void
+ {
+ exception_handling::assert(allocator_instance == nullptr,
+ "Calling register_heap_allocator_type can only be done once.");
+
+ switch (new_type)
+ {
+ case heap_allocator_type::NONE:
+ // Nothing to do
+ break;
+ case heap_allocator_type::BUMP: {
+ static bump_allocator allocator{HEAP_START, HEAP_START + HEAP_SIZE};
+ allocator_instance = &allocator;
+ break;
+ }
+ case heap_allocator_type::LINKED_LIST: {
+ static linked_list_allocator allocator{HEAP_START, HEAP_START + HEAP_SIZE};
+ allocator_instance = &allocator;
+ break;
+ }
+ }
+ }
+
+ auto global_heap_allocator::get() -> heap_allocator &
+ {
+ exception_handling::assert(allocator_instance != nullptr,
+ "Attempted to allocate or deallocate using the global_heap_allocator before "
+ "register_heap_allocation_type was called.");
+
+ return *allocator_instance;
+ }
+} // namespace teachos::arch::memory::heap
+
+auto operator new(std::size_t size) -> void *
+{
+ return teachos::arch::memory::heap::global_heap_allocator::allocate(size);
+}
+
+auto operator delete(void * pointer) noexcept -> void
+{
+ teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer);
+}
+
+auto operator delete(void * pointer, std::size_t size) noexcept -> void
+{
+ (void)size;
+ teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer);
+}
+
+auto operator new[](std::size_t size) -> void *
+{
+ return teachos::arch::memory::heap::global_heap_allocator::allocate(size);
+}
+
+auto operator delete[](void * pointer) noexcept -> void
+{
+ teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer);
+}
+
+auto operator delete[](void * pointer, std::size_t size) noexcept -> void
+{
+ (void)size;
+ teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer);
+}
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 e5bae21..a824c8a 100644
--- a/arch/x86_64/src/memory/heap/linked_list_allocator.cpp
+++ b/arch/x86_64/src/memory/heap/linked_list_allocator.cpp
@@ -3,6 +3,8 @@
#include "arch/exception_handling/assert.hpp"
#include "arch/exception_handling/panic.hpp"
+#include <algorithm>
+
namespace teachos::arch::memory::heap
{
linked_list_allocator::linked_list_allocator(std::size_t heap_start, std::size_t heap_end)
@@ -21,8 +23,9 @@ namespace teachos::arch::memory::heap
auto linked_list_allocator::allocate(std::size_t size) -> void *
{
- exception_handling::assert(size > min_allocatable_size(),
- "[Linked List Allocator] Allocated memory cannot be smaller than 16 bytes");
+ // Add size of size_t to the total allocated size, because we add a header that includes the size of the allocated
+ // block, to allow for deallocation without the need to call with the corresponding size
+ auto const total_size = size + sizeof(std::size_t);
mutex.lock();
memory_block * previous = nullptr;
@@ -30,17 +33,23 @@ namespace teachos::arch::memory::heap
while (current != nullptr)
{
- if (current->size == size)
+ 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 memory_address;
+ return reinterpret_cast<void *>(reinterpret_cast<std::size_t>(memory_address) + sizeof(std::size_t));
}
- else if (current->size >= size + min_allocatable_size())
+ else if (current->size >= total_size + min_allocatable_size())
{
- auto const memory_address = split_free_memory_block(previous, current, 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 memory_address;
+ return reinterpret_cast<void *>(reinterpret_cast<std::size_t>(memory_address) + sizeof(std::size_t));
}
previous = current;
@@ -50,14 +59,16 @@ namespace teachos::arch::memory::heap
exception_handling::panic("[Linked List Allocator] Out of memory");
}
- auto linked_list_allocator::deallocate(void * pointer, std::size_t size) -> void
+ auto linked_list_allocator::deallocate(void * pointer) noexcept -> void
{
- exception_handling::assert(size > min_allocatable_size(),
- "[Linked List Allocator] Allocated memory cannot be smaller than 16 bytes");
mutex.lock();
- auto const start_address = reinterpret_cast<std::size_t>(pointer);
- auto const end_address = start_address + size;
+ // Read configured header size of the complete allocated block
+ auto const header_pointer = reinterpret_cast<void *>(reinterpret_cast<std::size_t>(pointer) - sizeof(std::size_t));
+ auto const total_size = *reinterpret_cast<std::size_t *>(header_pointer);
+
+ auto const start_address = reinterpret_cast<std::size_t>(header_pointer);
+ auto const end_address = start_address + total_size;
memory_block * previous = nullptr;
auto current = first;
@@ -75,12 +86,12 @@ namespace teachos::arch::memory::heap
current = current->next;
}
- coalesce_free_memory_block(previous, current, pointer, size);
+ coalesce_free_memory_block(previous, current, header_pointer, total_size);
mutex.unlock();
}
- auto linked_list_allocator::remove_free_memory_block(memory_block * previous_block,
- memory_block * current_block) -> void *
+ auto linked_list_allocator::remove_free_memory_block(memory_block * previous_block, memory_block * current_block)
+ -> void *
{
return replace_free_memory_block(previous_block, current_block, current_block->next);
}
diff --git a/arch/x86_64/src/memory/main.cpp b/arch/x86_64/src/memory/main.cpp
index b978319..a6f91d9 100644
--- a/arch/x86_64/src/memory/main.cpp
+++ b/arch/x86_64/src/memory/main.cpp
@@ -4,7 +4,7 @@
#include "arch/memory/allocator/area_frame_allocator.hpp"
#include "arch/memory/cpu/control_register.hpp"
#include "arch/memory/cpu/msr.hpp"
-#include "arch/memory/heap/concept.hpp"
+#include "arch/memory/heap/heap_allocator.hpp"
#include "arch/memory/paging/active_page_table.hpp"
#include "arch/memory/paging/kernel_mapper.hpp"