From 9438c9203b7be20147b990ff05e1d99190d18928 Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 20 Feb 2025 09:38:28 +0000 Subject: added new and delete override --- arch/x86_64/include/arch/kernel/interrupt.hpp | 26 +++++++++++++++ .../arch/memory/heap/linked_list_allocator.hpp | 2 ++ .../arch/memory/heap/new_delete_override.hpp | 27 ++++++++++++++++ arch/x86_64/src/kernel/main.cpp | 37 ++++++++++------------ 4 files changed, 71 insertions(+), 21 deletions(-) create mode 100644 arch/x86_64/include/arch/kernel/interrupt.hpp create mode 100644 arch/x86_64/include/arch/memory/heap/new_delete_override.hpp diff --git a/arch/x86_64/include/arch/kernel/interrupt.hpp b/arch/x86_64/include/arch/kernel/interrupt.hpp new file mode 100644 index 0000000..521318d --- /dev/null +++ b/arch/x86_64/include/arch/kernel/interrupt.hpp @@ -0,0 +1,26 @@ +#ifndef TEACHOS_ARCH_X86_64_KERNEL_INTERRUPT_HPP +#define TEACHOS_ARCH_X86_64_KERNEL_INTERRUPT_HPP + +#include + +namespace teachos::arch::kernel +{ + struct stack_frame + { + std::uint16_t instruction_pointer; + std::uint16_t cs; + std::uint16_t flags; + std::uint16_t sp; + std::uint16_t ss; + }; + + /** + * @brief Handles an interrupt + * + * https://clang.llvm.org/docs/AttributeReference.html#interrupt-x86 + */ + __attribute__((interrupt)) extern "C" auto interrupt_handler(struct stack_frame * frame) -> void; + +} // namespace teachos::arch::kernel + +#endif // TEACHOS_ARCH_X86_64_KERNEL_INTERRUPT_HPP diff --git a/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp b/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp index 06b21bb..99c9218 100644 --- a/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp @@ -127,6 +127,8 @@ namespace teachos::arch::memory::heap shared::mutex mutex; ///< Mutex to ensure only one thread calls allocate or deallocate at once. }; + extern linked_list_allocator kernel_heap; + } // namespace teachos::arch::memory::heap #endif // TEACHOS_ARCH_X86_64_MEMORY_HEAP_LINKED_LIST_ALLOCATOR_HPP diff --git a/arch/x86_64/include/arch/memory/heap/new_delete_override.hpp b/arch/x86_64/include/arch/memory/heap/new_delete_override.hpp new file mode 100644 index 0000000..c51c737 --- /dev/null +++ b/arch/x86_64/include/arch/memory/heap/new_delete_override.hpp @@ -0,0 +1,27 @@ +#ifndef TEACHOS_ARCH_X86_64_MEMORY_NEW_DELETE_OVERRIDE_CONCEPT_HPP +#define TEACHOS_ARCH_X86_64_MEMORY_NEW_DELETE_OVERRIDE_CONCEPT_HPP + +#include "linked_list_allocator.hpp" +#include + +void * operator new(std::size_t size) { teachos::arch::memory::heap::kernel_heap.allocate(size); } + +void operator delete(void * pointer) noexcept { teachos::arch::memory::heap::kernel_heap.deallocate(pointer, 64); } + +void operator delete(void * pointer, std::size_t size) noexcept +{ + teachos::arch::memory::heap::kernel_heap.deallocate(pointer, size); +} + +void * operator new[](std::size_t size) { teachos::arch::memory::heap::kernel_heap.allocate(size); } + +void operator delete[](void * pointer) noexcept +{ + // NOPE +} + +void operator delete[](void * pointer, std::size_t size) noexcept +{ + teachos::arch::memory::heap::kernel_heap.deallocate(pointer, size); +} +#endif // TEACHOS_ARCH_X86_64_KERNEL_NEW_DELETE_OVERRIDE_HPP \ No newline at end of file diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index 681f960..a41132d 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -22,38 +22,33 @@ 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(static_cast(test) + 1)) - memory::multiboot::memory_information{}; + memory::heap::linked_list_allocator kernel_heap(memory::heap::HEAP_START, + memory::heap::HEAP_START + memory::heap::HEAP_SIZE); + + auto test2 = new memory::multiboot::memory_information{}; auto test4 = *test2; - auto test5 = *test3; test4.kernel_end = 5000; - test5.kernel_end = 3000; auto test6 = test4.kernel_end; - auto test7 = test5.kernel_end; auto test8 = memory::multiboot::read_multiboot2(); - if (test6 && test7 && test8.kernel_end) + if (test6 && test8.kernel_end) { video::vga::text::write("Heap test successful", video::vga::text::common_attributes::green_on_black); } test2->kernel_end = 2000; test2->kernel_start = 1000; test2->multiboot_start = 2000; - heap_allocator.deallocate(test, 1024); + delete test2; - 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 = 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 main() -> void -- cgit v1.2.3 From bff6c39a8d4571cd5c41e3926d5fc1428916f32c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Thu, 20 Feb 2025 10:07:03 +0000 Subject: Create global heap allocator attempt --- .../arch/memory/heap/global_heap_allocator.hpp | 46 ++++++++++++++++++++++ .../arch/memory/heap/new_delete_override.hpp | 27 ------------- arch/x86_64/src/kernel/main.cpp | 45 +++++++++++++-------- .../src/memory/heap/global_heap_allocator.cpp | 18 +++++++++ 4 files changed, 92 insertions(+), 44 deletions(-) create mode 100644 arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp delete mode 100644 arch/x86_64/include/arch/memory/heap/new_delete_override.hpp create mode 100644 arch/x86_64/src/memory/heap/global_heap_allocator.cpp diff --git a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp new file mode 100644 index 0000000..b7b2073 --- /dev/null +++ b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp @@ -0,0 +1,46 @@ +#ifndef TEACHOS_ARCH_X86_64_MEMORY_HEAP_GLOBAL_HEAP_ALLOCATOR_HPP +#define TEACHOS_ARCH_X86_64_MEMORY_HEAP_GLOBAL_HEAP_ALLOCATOR_HPP + +#include "arch/memory/heap/linked_list_allocator.hpp" + +namespace teachos::arch::memory::heap +{ + struct global_heap_allocator + { + static auto allocate(std::size_t size) -> void *; + + static auto deallocate(void * pointer, std::size_t size) -> void; + }; +} // 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, 64); +} + +auto operator delete(void * pointer, std::size_t size) noexcept -> void +{ + teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer, size); +} + +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, 64); +} + +auto operator delete[](void * pointer, std::size_t size) noexcept -> void +{ + teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer, size); +} + +#endif // TEACHOS_ARCH_X86_64_MEMORY_HEAP_GLOBAL_HEAP_ALLOCATOR_HPP diff --git a/arch/x86_64/include/arch/memory/heap/new_delete_override.hpp b/arch/x86_64/include/arch/memory/heap/new_delete_override.hpp deleted file mode 100644 index c51c737..0000000 --- a/arch/x86_64/include/arch/memory/heap/new_delete_override.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_MEMORY_NEW_DELETE_OVERRIDE_CONCEPT_HPP -#define TEACHOS_ARCH_X86_64_MEMORY_NEW_DELETE_OVERRIDE_CONCEPT_HPP - -#include "linked_list_allocator.hpp" -#include - -void * operator new(std::size_t size) { teachos::arch::memory::heap::kernel_heap.allocate(size); } - -void operator delete(void * pointer) noexcept { teachos::arch::memory::heap::kernel_heap.deallocate(pointer, 64); } - -void operator delete(void * pointer, std::size_t size) noexcept -{ - teachos::arch::memory::heap::kernel_heap.deallocate(pointer, size); -} - -void * operator new[](std::size_t size) { teachos::arch::memory::heap::kernel_heap.allocate(size); } - -void operator delete[](void * pointer) noexcept -{ - // NOPE -} - -void operator delete[](void * pointer, std::size_t size) noexcept -{ - teachos::arch::memory::heap::kernel_heap.deallocate(pointer, size); -} -#endif // TEACHOS_ARCH_X86_64_KERNEL_NEW_DELETE_OVERRIDE_HPP \ No newline at end of file diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index a41132d..f88ea41 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -2,7 +2,7 @@ #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,33 +22,44 @@ namespace teachos::arch::kernel auto heap_test() -> void { - memory::heap::linked_list_allocator kernel_heap(memory::heap::HEAP_START, - memory::heap::HEAP_START + memory::heap::HEAP_SIZE); - - auto test2 = new memory::multiboot::memory_information{}; + /*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(static_cast(test) + 1)) + memory::multiboot::memory_information{}; auto test4 = *test2; + auto test5 = *test3; test4.kernel_end = 5000; + test5.kernel_end = 3000; auto test6 = test4.kernel_end; + auto test7 = test5.kernel_end; auto test8 = memory::multiboot::read_multiboot2(); - if (test6 && test8.kernel_end) + if (test6 && test7 && test8.kernel_end) { video::vga::text::write("Heap test successful", video::vga::text::common_attributes::green_on_black); } test2->kernel_end = 2000; test2->kernel_start = 1000; test2->multiboot_start = 2000; - delete test2; + heap_allocator.deallocate(test, 1024); + + 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);*/ + + int * test = new int(); - // 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); + if (test == nullptr) + { + } } auto main() -> void 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..6c31de0 --- /dev/null +++ b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp @@ -0,0 +1,18 @@ + +#include "arch/memory/heap/global_heap_allocator.hpp" + +#include "arch/memory/heap/concept.hpp" + +namespace teachos::arch::memory::heap +{ + auto global_heap_allocator::allocate(std::size_t size) -> void * + { + static linked_list_allocator allocator{HEAP_START, HEAP_START + HEAP_SIZE}; + return allocator.allocate(size); + } + + auto global_heap_allocator::deallocate(void * pointer, std::size_t size) -> void + { + // allocator.deallocate(pointer, size); + } +} // namespace teachos::arch::memory::heap -- cgit v1.2.3 From 6c4ce82c3f9cc920bcde74fc10fdfd39b477b9f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Thu, 20 Feb 2025 10:41:11 +0000 Subject: Fix compilation issues --- arch/x86_64/CMakeLists.txt | 1 + .../arch/memory/heap/global_heap_allocator.hpp | 33 +++++------------- arch/x86_64/src/kernel/main.cpp | 28 +++------------ .../src/memory/heap/global_heap_allocator.cpp | 40 ++++++++++++++++++---- 4 files changed, 48 insertions(+), 54 deletions(-) diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt index c5624d8..9665846 100644 --- a/arch/x86_64/CMakeLists.txt +++ b/arch/x86_64/CMakeLists.txt @@ -59,6 +59,7 @@ target_sources("_memory" PRIVATE "src/memory/heap/bump_allocator.cpp" "src/memory/heap/memory_block.cpp" "src/memory/heap/linked_list_allocator.cpp" + "src/memory/heap/global_heap_allocator.cpp" "src/shared/mutex.cpp" ) diff --git a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp index b7b2073..871f4f8 100644 --- a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp @@ -10,37 +10,22 @@ namespace teachos::arch::memory::heap static auto allocate(std::size_t size) -> void *; static auto deallocate(void * pointer, std::size_t size) -> void; + + private: + static linked_list_allocator allocator; }; } // 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 new(std::size_t size) -> void *; -auto operator delete(void * pointer) noexcept -> void -{ - teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer, 64); -} +auto operator delete(void * pointer) noexcept -> void; -auto operator delete(void * pointer, std::size_t size) noexcept -> void -{ - teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer, size); -} +auto operator delete(void * pointer, std::size_t size) noexcept -> void; -auto operator new[](std::size_t size) -> void * -{ - return teachos::arch::memory::heap::global_heap_allocator::allocate(size); -} +auto operator new[](std::size_t size) -> void *; -auto operator delete[](void * pointer) noexcept -> void -{ - teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer, 64); -} +auto operator delete[](void * pointer) noexcept -> void; -auto operator delete[](void * pointer, std::size_t size) noexcept -> void -{ - teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer, size); -} +auto operator delete[](void * pointer, std::size_t size) noexcept -> void; #endif // TEACHOS_ARCH_X86_64_MEMORY_HEAP_GLOBAL_HEAP_ALLOCATOR_HPP diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index f88ea41..ed9fc58 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -22,12 +22,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(static_cast(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,24 +38,8 @@ namespace teachos::arch::kernel test2->kernel_end = 2000; test2->kernel_start = 1000; test2->multiboot_start = 2000; - heap_allocator.deallocate(test, 1024); - - 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);*/ - - int * test = new int(); - - if (test == nullptr) - { - } + delete test2; + delete test3; } auto main() -> void diff --git a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp index 6c31de0..11848ed 100644 --- a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp +++ b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp @@ -5,14 +5,42 @@ namespace teachos::arch::memory::heap { - auto global_heap_allocator::allocate(std::size_t size) -> void * - { - static linked_list_allocator allocator{HEAP_START, HEAP_START + HEAP_SIZE}; - return allocator.allocate(size); - } + static global_heap_allocator::allocator = linked_list_allocator{HEAP_START, HEAP_START + HEAP_SIZE}; + + auto global_heap_allocator::allocate(std::size_t size) -> void * { return allocator.allocate(size); } auto global_heap_allocator::deallocate(void * pointer, std::size_t size) -> void { - // allocator.deallocate(pointer, size); + allocator.deallocate(pointer, size); } } // 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, 64); +} + +auto operator delete(void * pointer, std::size_t size) noexcept -> void +{ + teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer, size); +} + +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, 64); +} + +auto operator delete[](void * pointer, std::size_t size) noexcept -> void +{ + teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer, size); +} -- cgit v1.2.3 From cd502936227e48a36d9e933d26aac2ee29d3bc29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Thu, 20 Feb 2025 10:58:17 +0000 Subject: Add singelton implementation for global heap allocator --- .../include/arch/memory/heap/global_heap_allocator.hpp | 2 +- arch/x86_64/src/memory/heap/global_heap_allocator.cpp | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp index 871f4f8..f391936 100644 --- a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp @@ -12,7 +12,7 @@ namespace teachos::arch::memory::heap static auto deallocate(void * pointer, std::size_t size) -> void; private: - static linked_list_allocator allocator; + static auto get_underlying_allocator() -> linked_list_allocator &; }; } // namespace teachos::arch::memory::heap diff --git a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp index 11848ed..4e3a274 100644 --- a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp +++ b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp @@ -5,13 +5,17 @@ namespace teachos::arch::memory::heap { - static global_heap_allocator::allocator = linked_list_allocator{HEAP_START, HEAP_START + HEAP_SIZE}; - - auto global_heap_allocator::allocate(std::size_t size) -> void * { return allocator.allocate(size); } + auto global_heap_allocator::allocate(std::size_t size) -> void * { return get_underlying_allocator().allocate(size); } auto global_heap_allocator::deallocate(void * pointer, std::size_t size) -> void { - allocator.deallocate(pointer, size); + get_underlying_allocator().deallocate(pointer, size); + } + + auto global_heap_allocator::get_underlying_allocator() -> linked_list_allocator & + { + static linked_list_allocator allocator{HEAP_START, HEAP_START + HEAP_SIZE}; + return allocator; } } // namespace teachos::arch::memory::heap -- cgit v1.2.3 From 27874721a35fe7ccde843c7ab88ab72e74fe6b42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Thu, 20 Feb 2025 12:14:30 +0000 Subject: Make allocation type configurable --- .../arch/memory/heap/global_heap_allocator.hpp | 13 ++++++- .../src/memory/heap/global_heap_allocator.cpp | 45 ++++++++++++++++++---- 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp index f391936..a4ece57 100644 --- a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp @@ -5,6 +5,13 @@ namespace teachos::arch::memory::heap { + enum class heap_allocator_type : uint8_t + { + NONE, + BUMP, + LINKED_LIST + }; + struct global_heap_allocator { static auto allocate(std::size_t size) -> void *; @@ -12,7 +19,11 @@ namespace teachos::arch::memory::heap static auto deallocate(void * pointer, std::size_t size) -> void; private: - static auto get_underlying_allocator() -> linked_list_allocator &; + static heap_allocator_type allocator_type; + + static auto register_heap_allocator_type(heap_allocator_type new_type) -> void; + + static auto create_or_get() -> linked_list_allocator &; }; } // namespace teachos::arch::memory::heap diff --git a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp index 4e3a274..d82606e 100644 --- a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp +++ b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp @@ -1,21 +1,52 @@ #include "arch/memory/heap/global_heap_allocator.hpp" +#include "arch/exception_handling/assert.hpp" +#include "arch/exception_handling/panic.hpp" +#include "arch/memory/heap/bump_allocator.hpp" #include "arch/memory/heap/concept.hpp" +#include "arch/memory/heap/linked_list_allocator.hpp" namespace teachos::arch::memory::heap { - auto global_heap_allocator::allocate(std::size_t size) -> void * { return get_underlying_allocator().allocate(size); } + heap_allocator_type global_heap_allocator::allocator_type = heap_allocator_type::NONE; + + auto global_heap_allocator::allocate(std::size_t size) -> void * { return create_or_get().allocate(size); } auto global_heap_allocator::deallocate(void * pointer, std::size_t size) -> void { - get_underlying_allocator().deallocate(pointer, size); + create_or_get().deallocate(pointer, size); } - auto global_heap_allocator::get_underlying_allocator() -> linked_list_allocator & + auto global_heap_allocator::register_heap_allocator_type(heap_allocator_type new_type) -> void { - static linked_list_allocator allocator{HEAP_START, HEAP_START + HEAP_SIZE}; - return allocator; + allocator_type = new_type; + } + + auto global_heap_allocator::create_or_get() -> linked_list_allocator & + { + linked_list_allocator * allocator_ptr = nullptr; + + switch (allocator_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_ptr = &allocator; + break; + } + case heap_allocator_type::LINKED_LIST: { + static linked_list_allocator allocator{HEAP_START, HEAP_START + HEAP_SIZE}; + allocator_ptr = &allocator; + break; + } + } + exception_handling::assert(allocator_ptr != nullptr, + "Attempted to allocate or deallocate using the global_heap_allocator before " + "register_heap_allocation_type was called."); + return *allocator_ptr; } } // namespace teachos::arch::memory::heap @@ -26,7 +57,7 @@ auto operator new(std::size_t size) -> void * auto operator delete(void * pointer) noexcept -> void { - teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer, 64); + teachos::arch::exception_handling::panic("Called delete operator without passing required size attribute"); } auto operator delete(void * pointer, std::size_t size) noexcept -> void @@ -41,7 +72,7 @@ auto operator new[](std::size_t size) -> void * auto operator delete[](void * pointer) noexcept -> void { - teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer, 64); + teachos::arch::exception_handling::panic("Called delete[] operator without passing required size attribute"); } auto operator delete[](void * pointer, std::size_t size) noexcept -> void -- cgit v1.2.3 From 00fd8cf8f72d6c5c3d6150f3ec833ded9e34b2b1 Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 20 Feb 2025 16:05:19 +0000 Subject: add heap_allocator base class --- .../include/arch/memory/heap/bump_allocator.hpp | 4 +- .../arch/memory/heap/global_heap_allocator.hpp | 6 +-- .../include/arch/memory/heap/heap_allocator.hpp | 16 ++++++++ .../arch/memory/heap/linked_list_allocator.hpp | 3 +- arch/x86_64/src/kernel/main.cpp | 4 +- .../src/memory/heap/global_heap_allocator.cpp | 48 +++++++++++++--------- 6 files changed, 56 insertions(+), 25 deletions(-) create mode 100644 arch/x86_64/include/arch/memory/heap/heap_allocator.hpp diff --git a/arch/x86_64/include/arch/memory/heap/bump_allocator.hpp b/arch/x86_64/include/arch/memory/heap/bump_allocator.hpp index 545b72f..209f8b3 100644 --- a/arch/x86_64/include/arch/memory/heap/bump_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/bump_allocator.hpp @@ -1,6 +1,8 @@ #ifndef TEACHOS_ARCH_X86_64_MEMORY_HEAP_BUMP_ALLOCATOR_HPP #define TEACHOS_ARCH_X86_64_MEMORY_HEAP_BUMP_ALLOCATOR_HPP +#include "arch/memory/heap/heap_allocator.hpp" + #include #include @@ -10,7 +12,7 @@ namespace teachos::arch::memory::heap * @brief Simple heap allocator, which allocates linearly and leaks all allocated memory, because it does not really * deallocate anything. */ - struct bump_allocator + struct bump_allocator : heap_allocator { /** * @brief Constructor. diff --git a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp index a4ece57..e8555df 100644 --- a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp @@ -14,6 +14,8 @@ namespace teachos::arch::memory::heap struct global_heap_allocator { + static auto register_heap_allocator_type(heap_allocator_type new_type) -> void; + static auto allocate(std::size_t size) -> void *; static auto deallocate(void * pointer, std::size_t size) -> void; @@ -21,9 +23,7 @@ namespace teachos::arch::memory::heap private: static heap_allocator_type allocator_type; - static auto register_heap_allocator_type(heap_allocator_type new_type) -> void; - - static auto create_or_get() -> linked_list_allocator &; + static auto create_or_get() -> heap_allocator &; }; } // namespace teachos::arch::memory::heap diff --git a/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp new file mode 100644 index 0000000..9e37bd4 --- /dev/null +++ b/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp @@ -0,0 +1,16 @@ +#ifndef TEACHOS_ARCH_X86_64_MEMORY_HEAP_HEAP_ALLOCATOR_HPP +#define TEACHOS_ARCH_X86_64_MEMORY_HEAP_HEAP_ALLOCATOR_HPP + +#include + +namespace teachos::arch::memory::heap +{ + struct heap_allocator + { + virtual auto allocate(std::size_t size) -> void * = 0; + + virtual auto deallocate(void * pointer, std::size_t size) -> void = 0; + }; +} // namespace teachos::arch::memory::heap + +#endif // TEACHOS_ARCH_X86_64_MEMORY_HEAP_HEAP_ALLOCATOR_HPP diff --git a/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp b/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp index 99c9218..966e28e 100644 --- a/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp @@ -1,6 +1,7 @@ #ifndef TEACHOS_ARCH_X86_64_MEMORY_HEAP_LINKED_LIST_ALLOCATOR_HPP #define TEACHOS_ARCH_X86_64_MEMORY_HEAP_LINKED_LIST_ALLOCATOR_HPP +#include "arch/memory/heap/heap_allocator.hpp" #include "arch/memory/heap/memory_block.hpp" #include "arch/shared/mutex.hpp" @@ -10,7 +11,7 @@ namespace teachos::arch::memory::heap * @brief Sorted by address list of memory holes (free memory). Uses free holes itself to save the information, * containing the size and pointer to the next hole. Resulting in a singly linked list. */ - struct linked_list_allocator + struct linked_list_allocator : heap_allocator { /** * @brief Constructor. diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index ed9fc58..7c03644 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -50,8 +50,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_type(memory::heap::heap_allocator_type::LINKED_LIST); + heap_test(); } } // namespace teachos::arch::kernel diff --git a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp index d82606e..243f5d8 100644 --- a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp +++ b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp @@ -1,10 +1,10 @@ - #include "arch/memory/heap/global_heap_allocator.hpp" #include "arch/exception_handling/assert.hpp" #include "arch/exception_handling/panic.hpp" #include "arch/memory/heap/bump_allocator.hpp" #include "arch/memory/heap/concept.hpp" +#include "arch/memory/heap/heap_allocator.hpp" #include "arch/memory/heap/linked_list_allocator.hpp" namespace teachos::arch::memory::heap @@ -23,29 +23,33 @@ namespace teachos::arch::memory::heap allocator_type = new_type; } - auto global_heap_allocator::create_or_get() -> linked_list_allocator & + auto global_heap_allocator::create_or_get() -> heap_allocator & { - linked_list_allocator * allocator_ptr = nullptr; + static heap_allocator * allocator_ptr = nullptr; - switch (allocator_type) + if (allocator_ptr == nullptr) { - 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_ptr = &allocator; - break; - } - case heap_allocator_type::LINKED_LIST: { - static linked_list_allocator allocator{HEAP_START, HEAP_START + HEAP_SIZE}; - allocator_ptr = &allocator; - break; + switch (allocator_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_ptr = &allocator; + break; + } + case heap_allocator_type::LINKED_LIST: { + static linked_list_allocator allocator{HEAP_START, HEAP_START + HEAP_SIZE}; + allocator_ptr = &allocator; + break; + } } + exception_handling::assert(allocator_ptr != nullptr, + "Attempted to allocate or deallocate using the global_heap_allocator before " + "register_heap_allocation_type was called."); } - exception_handling::assert(allocator_ptr != nullptr, - "Attempted to allocate or deallocate using the global_heap_allocator before " - "register_heap_allocation_type was called."); + return *allocator_ptr; } } // namespace teachos::arch::memory::heap @@ -57,6 +61,9 @@ auto operator new(std::size_t size) -> void * auto operator delete(void * pointer) noexcept -> void { + if (pointer == nullptr) + { + } teachos::arch::exception_handling::panic("Called delete operator without passing required size attribute"); } @@ -72,6 +79,9 @@ auto operator new[](std::size_t size) -> void * auto operator delete[](void * pointer) noexcept -> void { + if (pointer == nullptr) + { + } teachos::arch::exception_handling::panic("Called delete[] operator without passing required size attribute"); } -- cgit v1.2.3 From 405b5b1018397bff48e32c75e10a6b3b58bb6a20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Fri, 21 Feb 2025 14:13:39 +0000 Subject: Update factory method code --- .../include/arch/memory/heap/bump_allocator.hpp | 4 +- arch/x86_64/include/arch/memory/heap/concept.hpp | 22 ------- .../arch/memory/heap/global_heap_allocator.hpp | 8 +-- .../include/arch/memory/heap/heap_allocator.hpp | 5 ++ arch/x86_64/src/kernel/main.cpp | 1 - arch/x86_64/src/memory/cpu/control_register.cpp | 8 +-- .../src/memory/heap/global_heap_allocator.cpp | 75 +++++++++------------- arch/x86_64/src/memory/main.cpp | 2 +- 8 files changed, 46 insertions(+), 79 deletions(-) delete mode 100644 arch/x86_64/include/arch/memory/heap/concept.hpp diff --git a/arch/x86_64/include/arch/memory/heap/bump_allocator.hpp b/arch/x86_64/include/arch/memory/heap/bump_allocator.hpp index 209f8b3..d5f4561 100644 --- a/arch/x86_64/include/arch/memory/heap/bump_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/bump_allocator.hpp @@ -34,7 +34,7 @@ namespace teachos::arch::memory::heap * @param size Amount of memory to allocate. * @return Address of the first byte to the allocated area */ - auto allocate(std::size_t size) -> void *; + auto allocate(std::size_t size) -> void * override; /** * @brief Deallocates heap memory at the specified location. @@ -44,7 +44,7 @@ namespace teachos::arch::memory::heap * @param pointer Pointer to the location which should be deallocated. * @param size Size of the underlying memory area we want to deallocate. */ - auto deallocate(void * pointer, std::size_t size) -> void; + auto deallocate(void * pointer, std::size_t size) -> void override; private: std::size_t heap_start; ///< Start of the allocatable heap area diff --git a/arch/x86_64/include/arch/memory/heap/concept.hpp b/arch/x86_64/include/arch/memory/heap/concept.hpp deleted file mode 100644 index e22e35f..0000000 --- a/arch/x86_64/include/arch/memory/heap/concept.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_MEMORY_HEAP_CONCEPT_HPP -#define TEACHOS_ARCH_X86_64_MEMORY_HEAP_CONCEPT_HPP - -#include - -namespace teachos::arch::memory::heap -{ - std::size_t constexpr HEAP_START = 0x100000000; - std::size_t constexpr HEAP_SIZE = 100 * 1024; - - /** - * @brief Heap allocator concept required for allocating and managing free space on the heap. - */ - template - concept HeapAllocator = requires(T t, uint8_t * pointer, std::size_t size) { - { t.allocate(size) } -> std::same_as; - { t.deallocate(pointer, size) } -> std::same_as; - }; - -} // namespace teachos::arch::memory::heap - -#endif // TEACHOS_ARCH_X86_64_MEMORY_HEAP_CONCEPT_HPP diff --git a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp index e8555df..1b1d964 100644 --- a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_ARCH_X86_64_MEMORY_HEAP_GLOBAL_HEAP_ALLOCATOR_HPP #define TEACHOS_ARCH_X86_64_MEMORY_HEAP_GLOBAL_HEAP_ALLOCATOR_HPP -#include "arch/memory/heap/linked_list_allocator.hpp" +#include "arch/memory/heap/heap_allocator.hpp" namespace teachos::arch::memory::heap { @@ -14,16 +14,16 @@ namespace teachos::arch::memory::heap struct global_heap_allocator { - static auto register_heap_allocator_type(heap_allocator_type new_type) -> void; + static auto register_heap_allocator(heap_allocator_type new_type) -> void; static auto allocate(std::size_t size) -> void *; static auto deallocate(void * pointer, std::size_t size) -> void; private: - static heap_allocator_type allocator_type; + static heap_allocator * allocator_instance; - static auto create_or_get() -> heap_allocator &; + static auto get() -> heap_allocator &; }; } // namespace teachos::arch::memory::heap diff --git a/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp index 9e37bd4..62ba963 100644 --- a/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp @@ -5,8 +5,13 @@ namespace teachos::arch::memory::heap { + std::size_t constexpr HEAP_START = 0x100000000; + std::size_t constexpr HEAP_SIZE = 100 * 1024; + struct heap_allocator { + virtual ~heap_allocator() {} + virtual auto allocate(std::size_t size) -> void * = 0; virtual auto deallocate(void * pointer, std::size_t size) -> void = 0; diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index 7c03644..f102a3a 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -1,7 +1,6 @@ #include "arch/kernel/main.hpp" #include "arch/memory/heap/bump_allocator.hpp" -#include "arch/memory/heap/concept.hpp" #include "arch/memory/heap/global_heap_allocator.hpp" #include "arch/memory/main.hpp" #include "arch/memory/multiboot/reader.hpp" 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 @@ -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/global_heap_allocator.cpp b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp index 243f5d8..71fe775 100644 --- a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp +++ b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp @@ -1,56 +1,47 @@ #include "arch/memory/heap/global_heap_allocator.hpp" #include "arch/exception_handling/assert.hpp" -#include "arch/exception_handling/panic.hpp" #include "arch/memory/heap/bump_allocator.hpp" -#include "arch/memory/heap/concept.hpp" -#include "arch/memory/heap/heap_allocator.hpp" #include "arch/memory/heap/linked_list_allocator.hpp" namespace teachos::arch::memory::heap { - heap_allocator_type global_heap_allocator::allocator_type = heap_allocator_type::NONE; + heap_allocator * global_heap_allocator::allocator_instance = nullptr; - auto global_heap_allocator::allocate(std::size_t size) -> void * { return create_or_get().allocate(size); } + auto global_heap_allocator::allocate(std::size_t size) -> void * { return get().allocate(size); } - auto global_heap_allocator::deallocate(void * pointer, std::size_t size) -> void - { - create_or_get().deallocate(pointer, size); - } + auto global_heap_allocator::deallocate(void * pointer, std::size_t size) -> void { get().deallocate(pointer, size); } - auto global_heap_allocator::register_heap_allocator_type(heap_allocator_type new_type) -> void + auto global_heap_allocator::register_heap_allocator(heap_allocator_type new_type) -> void { - allocator_type = new_type; - } + exception_handling::assert(allocator_instance != nullptr, + "Calling register_heap_allocator_type can only be done once."); - auto global_heap_allocator::create_or_get() -> heap_allocator & - { - static heap_allocator * allocator_ptr = nullptr; - - if (allocator_ptr == nullptr) + switch (new_type) { - switch (allocator_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_ptr = &allocator; - break; - } - case heap_allocator_type::LINKED_LIST: { - static linked_list_allocator allocator{HEAP_START, HEAP_START + HEAP_SIZE}; - allocator_ptr = &allocator; - break; - } + 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; } - exception_handling::assert(allocator_ptr != nullptr, - "Attempted to allocate or deallocate using the global_heap_allocator before " - "register_heap_allocation_type was called."); } + } - return *allocator_ptr; + 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 @@ -61,10 +52,8 @@ auto operator new(std::size_t size) -> void * auto operator delete(void * pointer) noexcept -> void { - if (pointer == nullptr) - { - } - teachos::arch::exception_handling::panic("Called delete operator without passing required size attribute"); + teachos::arch::exception_handling::assert(false && pointer == nullptr, + "Called delete operator without passing required size attribute"); } auto operator delete(void * pointer, std::size_t size) noexcept -> void @@ -79,10 +68,8 @@ auto operator new[](std::size_t size) -> void * auto operator delete[](void * pointer) noexcept -> void { - if (pointer == nullptr) - { - } - teachos::arch::exception_handling::panic("Called delete[] operator without passing required size attribute"); + teachos::arch::exception_handling::assert(false && pointer == nullptr, + "Called delete[] operator without passing required size attribute"); } auto operator delete[](void * pointer, std::size_t size) noexcept -> void 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" -- cgit v1.2.3 From 93cc8aa1c0e4ba991f0503c609702e1c63a240c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Fri, 21 Feb 2025 15:23:51 +0000 Subject: Add documentation to new components --- .../arch/memory/heap/global_heap_allocator.hpp | 49 ++++++++++++++++++++-- .../include/arch/memory/heap/heap_allocator.hpp | 22 ++++++++++ .../include/arch/memory/heap/memory_block.hpp | 1 - .../include/arch/memory/paging/page_entry.hpp | 3 +- arch/x86_64/src/kernel/main.cpp | 2 +- 5 files changed, 69 insertions(+), 8 deletions(-) diff --git a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp index 1b1d964..6719bec 100644 --- a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp @@ -5,24 +5,65 @@ namespace teachos::arch::memory::heap { + /** + * @brief Possible types that should be constructed by the register_heap_allocator factory method. + * Creates the underlying heap allocator instance that is then used by all global allocations using new and delete + */ enum class heap_allocator_type : uint8_t { - NONE, - BUMP, - LINKED_LIST + NONE, ///< Don't use any heap allocation implementation, this will result in all calls of new and delte halting + ///< further execution of the kernel + BUMP, ///< Use the bump allocator as the heap allocation implementation, be aware that using this allocator leaks + ///< memory, because there is no delete implementation + LINKED_LIST ///< Use the linked list allocator as the heap implementation, recommended because it does not leak + ///< memory and }; + /** + * @brief Global instance of a heap allocator implementation created by the factory method pattern @see + * https://refactoring.guru/design-patterns/factory-method for more information. + * + * @note Can only be registered once and only once the kernel and the heap part of the kernel has been remapped + * successfully. If the instance is created before than the device will abort, because it acceses unmapped memory + * areas. + */ struct global_heap_allocator { + /** + * @brief Registers the heap allocation implementation that should be used by the global heap allocator. + * Meaning all future calls to the global new or delete will be forwarded to the allocate and deallocate calls of + * the underlying heap allocation implementation + * + * @param new_type Type of the heap allocation implementation we want to instantiate + */ static auto register_heap_allocator(heap_allocator_type new_type) -> void; + /** + * @brief Allocates the given amount of memory and returns the pointer to the start of the allocatable memory area. + * Simply forwards the call to the allocate method of the registered heap_allocation implementation + * + * @param size Amount of bytes that should be allocated + * @return void* Pointer to the start of the allocatable memory area + */ static auto allocate(std::size_t size) -> void *; + /** + * @brief Deallocated the given amount of memory starting from the given pointer address. + * Simply forwards the call to the deallocate method of the registered heap_allocation implementation + * + * @param pointer Previously allocated memory area, that should now be freed + * @param size Size of the memory area we want to free + */ static auto deallocate(void * pointer, std::size_t size) -> void; private: - static heap_allocator * allocator_instance; + static heap_allocator * allocator_instance; ///< Instance used to actually allocate and deallocate + /** + * @brief Either returns the previously registered heap allocated or halts furthere execution + * + * @return Reference to the registered heap allocation + */ static auto get() -> heap_allocator &; }; } // namespace teachos::arch::memory::heap diff --git a/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp index 62ba963..1519155 100644 --- a/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp @@ -8,12 +8,34 @@ namespace teachos::arch::memory::heap std::size_t constexpr HEAP_START = 0x100000000; std::size_t constexpr HEAP_SIZE = 100 * 1024; + /** + * @brief Heap allocator interface containing methods required to allocate and deallocate heap memory areas + */ struct heap_allocator { + /** + * @brief Virtual default destructor, created to ensure that if a pointer to this class is used and deleted, we will + * also call the derived base class destructor. Deleting a base class destructor that does not have a virtual + * destructor is undefined behaviour, because the derived class destructor originally instantiated with new is never + * called. This can cause potential memory leaks, because derived classes can not clean up their internal members as + * expected and instead simply leak them + */ virtual ~heap_allocator() {} + /** + * @brief Allocates the given amount of memory and returns the pointer to the start of the allocatable memory area + * + * @param size Amount of bytes that should be allocated + * @return void* Pointer to the start of the allocatable memory area + */ virtual auto allocate(std::size_t size) -> void * = 0; + /** + * @brief Deallocated the given amount of memory starting from the given pointer address + * + * @param pointer Previously allocated memory area, that should now be freed + * @param size Size of the memory area we want to free + */ virtual auto deallocate(void * pointer, std::size_t size) -> void = 0; }; } // namespace teachos::arch::memory::heap diff --git a/arch/x86_64/include/arch/memory/heap/memory_block.hpp b/arch/x86_64/include/arch/memory/heap/memory_block.hpp index b9a2254..e1cd288 100644 --- a/arch/x86_64/include/arch/memory/heap/memory_block.hpp +++ b/arch/x86_64/include/arch/memory/heap/memory_block.hpp @@ -32,7 +32,6 @@ namespace teachos::arch::memory::heap ///< size variable and the pointer to the next hole. memory_block * next; ///< Optional pointer to the next free memory, holds nullptr if there is none. }; - } // namespace teachos::arch::memory::heap #endif // TEACHOS_ARCH_X86_64_MEMORY_HEAP_MEMORY_BLOCK_HPP diff --git a/arch/x86_64/include/arch/memory/paging/page_entry.hpp b/arch/x86_64/include/arch/memory/paging/page_entry.hpp index 876ea3c..1de31b5 100644 --- a/arch/x86_64/include/arch/memory/paging/page_entry.hpp +++ b/arch/x86_64/include/arch/memory/paging/page_entry.hpp @@ -49,14 +49,13 @@ namespace teachos::arch::memory::paging explicit entry(uint64_t flags); /** - * @brief Converts the given elf section flags into the corresponding correct entry flags. + * @brief Creates a new entry converting the given elf section flags into the corresponding correct entry flags. * * @note Enables us to set the correct flags on a entry depending on which elf section it is contained in. For * example entries of .text sections should be executable and read only or entries of .data sections should be * writable but not executable. * * @param elf_flags Elf section flags we want to convert into entry flags. - * @return Entry that has the corresponding bit flags set. */ explicit entry(multiboot::elf_section_flags elf_flags); diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index f102a3a..f3518a8 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -51,7 +51,7 @@ namespace teachos::arch::kernel memory::initialize_memory_management(); // stack_overflow_test(0); - memory::heap::global_heap_allocator::register_heap_allocator_type(memory::heap::heap_allocator_type::LINKED_LIST); + memory::heap::global_heap_allocator::register_heap_allocator(memory::heap::heap_allocator_type::LINKED_LIST); heap_test(); } -- cgit v1.2.3 From fcc586a846562e024c1cd77042634494cf380bd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Sun, 23 Feb 2025 10:27:46 +0000 Subject: Adjust linked list allocator to allow for deallocation without passing size parameter and with arbitrary size --- .../include/arch/memory/heap/bump_allocator.hpp | 15 ++------ .../arch/memory/heap/global_heap_allocator.hpp | 5 ++- .../include/arch/memory/heap/heap_allocator.hpp | 6 ++-- .../arch/memory/heap/linked_list_allocator.hpp | 21 +++-------- arch/x86_64/src/kernel/main.cpp | 3 ++ arch/x86_64/src/memory/heap/bump_allocator.cpp | 4 +-- .../src/memory/heap/global_heap_allocator.cpp | 20 ++++++----- .../src/memory/heap/linked_list_allocator.cpp | 41 ++++++++++++++-------- 8 files changed, 56 insertions(+), 59 deletions(-) diff --git a/arch/x86_64/include/arch/memory/heap/bump_allocator.hpp b/arch/x86_64/include/arch/memory/heap/bump_allocator.hpp index d5f4561..74734af 100644 --- a/arch/x86_64/include/arch/memory/heap/bump_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/bump_allocator.hpp @@ -28,23 +28,14 @@ namespace teachos::arch::memory::heap // Nothing to do } - /** - * @brief Allocates the specified amount of memory in the heap. - * - * @param size Amount of memory to allocate. - * @return Address of the first byte to the allocated area - */ auto allocate(std::size_t size) -> void * override; /** - * @brief Deallocates heap memory at the specified location. - * - * @note Simply does nothing, because this allocator leaks all memory. + * @copybrief heap_allocator::deallocate * - * @param pointer Pointer to the location which should be deallocated. - * @param size Size of the underlying memory area we want to deallocate. + * @note Simply does nothing, because this allocator leaks all memory */ - auto deallocate(void * pointer, std::size_t size) -> void override; + auto deallocate(void * pointer) -> void override; private: std::size_t heap_start; ///< Start of the allocatable heap area diff --git a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp index 6719bec..a1621b5 100644 --- a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp @@ -48,13 +48,12 @@ namespace teachos::arch::memory::heap static auto allocate(std::size_t size) -> void *; /** - * @brief Deallocated the given amount of memory starting from the given pointer address. + * @brief Deallocated all memory associated with the memory area starting from the given pointer address. * Simply forwards the call to the deallocate method of the registered heap_allocation implementation * * @param pointer Previously allocated memory area, that should now be freed - * @param size Size of the memory area we want to free */ - static auto deallocate(void * pointer, std::size_t size) -> void; + static auto deallocate(void * pointer) -> void; private: static heap_allocator * allocator_instance; ///< Instance used to actually allocate and deallocate diff --git a/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp index 1519155..01657f2 100644 --- a/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp @@ -31,12 +31,12 @@ namespace teachos::arch::memory::heap virtual auto allocate(std::size_t size) -> void * = 0; /** - * @brief Deallocated the given amount of memory starting from the given pointer address + * @brief Deallocates all memory associated with the given pointer address. + * Simply deallocates the amount of memory created with the corresponding call to allocate * * @param pointer Previously allocated memory area, that should now be freed - * @param size Size of the memory area we want to free */ - virtual auto deallocate(void * pointer, std::size_t size) -> void = 0; + virtual auto deallocate(void * pointer) -> void = 0; }; } // namespace teachos::arch::memory::heap diff --git a/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp b/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp index 966e28e..d53756d 100644 --- a/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp @@ -22,7 +22,7 @@ namespace teachos::arch::memory::heap linked_list_allocator(std::size_t heap_start, std::size_t heap_end); /** - * @brief Allocates the specified amount of memory in the heap. + * @copybrief heap_allocator::allocate * * @note The specified size is used to find a free memory block with the exact same size, meaning we can remove that * free memory block from the free list and simply return its address. Or it has to be big enough to hold the size @@ -32,21 +32,10 @@ namespace teachos::arch::memory::heap * they received more memory than wanted. Therefore the memory would simply be unused and because it is neither * allocated nor deallocated would never be indexed by the free memory list. We would therefore permanently loose * that memory, to prevent that allocation into free memory blocks like that are impossible. - * - * @param size Amount of memory to allocate. - * @return Address of the first byte to the allocated area */ - auto allocate(std::size_t size) -> void *; + auto allocate(std::size_t size) -> void * override; - /** - * @brief Deallocates heap memory at the specified location. - * - * @note Simply does nothing, because this allocator leaks all memory. - * - * @param pointer Pointer to the location which should be deallocated. - * @param size Size of the underlying memory area we want to deallocate. - */ - auto deallocate(void * pointer, std::size_t size) -> void; + auto deallocate(void * pointer) -> void override; private: /** @@ -79,8 +68,8 @@ namespace teachos::arch::memory::heap * * @return Previous start address of the memory block we just split, because it can now be used for the allocation. */ - auto split_free_memory_block(memory_block * previous_block, memory_block * current_block, - std::size_t size) -> void *; + auto split_free_memory_block(memory_block * previous_block, memory_block * current_block, std::size_t size) + -> void *; /** * @brief Removes a free memory block from the free list and returns its address so the caller can allocate into it. diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index f3518a8..472aed5 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -39,6 +39,9 @@ namespace teachos::arch::kernel test2->multiboot_start = 2000; delete test2; delete test3; + + auto test9 = new int(50); + delete test9; } auto main() -> void diff --git a/arch/x86_64/src/memory/heap/bump_allocator.cpp b/arch/x86_64/src/memory/heap/bump_allocator.cpp index bbf2021..a9fb121 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) -> 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 index 71fe775..09db9ba 100644 --- a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp +++ b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp @@ -10,11 +10,11 @@ namespace teachos::arch::memory::heap auto global_heap_allocator::allocate(std::size_t size) -> void * { return get().allocate(size); } - auto global_heap_allocator::deallocate(void * pointer, std::size_t size) -> void { get().deallocate(pointer, size); } + auto global_heap_allocator::deallocate(void * pointer) -> void { get().deallocate(pointer); } auto global_heap_allocator::register_heap_allocator(heap_allocator_type new_type) -> void { - exception_handling::assert(allocator_instance != nullptr, + exception_handling::assert(allocator_instance == nullptr, "Calling register_heap_allocator_type can only be done once."); switch (new_type) @@ -52,13 +52,15 @@ auto operator new(std::size_t size) -> void * auto operator delete(void * pointer) noexcept -> void { - teachos::arch::exception_handling::assert(false && pointer == nullptr, - "Called delete operator without passing required size attribute"); + teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer); } auto operator delete(void * pointer, std::size_t size) noexcept -> void { - teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer, size); + if (size) + { + } + teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer); } auto operator new[](std::size_t size) -> void * @@ -68,11 +70,13 @@ auto operator new[](std::size_t size) -> void * auto operator delete[](void * pointer) noexcept -> void { - teachos::arch::exception_handling::assert(false && pointer == nullptr, - "Called delete[] operator without passing required size attribute"); + teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer); } auto operator delete[](void * pointer, std::size_t size) noexcept -> void { - teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer, size); + if (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..9beb466 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 + 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(reinterpret_cast(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(reinterpret_cast(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) -> 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(pointer); - auto const end_address = start_address + size; + // Read configured header size of the complete allocated block + auto const header_pointer = reinterpret_cast(reinterpret_cast(pointer) - sizeof(std::size_t)); + auto const total_size = *reinterpret_cast(header_pointer); + + auto const start_address = reinterpret_cast(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); } -- cgit v1.2.3 From 20f2a4a3e9b8100544a7b3dd57c5959dc6dc066f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Sun, 23 Feb 2025 14:37:28 +0000 Subject: Remove useless if statements --- arch/x86_64/src/memory/heap/global_heap_allocator.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp index 09db9ba..235c544 100644 --- a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp +++ b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp @@ -57,9 +57,7 @@ auto operator delete(void * pointer) noexcept -> void auto operator delete(void * pointer, std::size_t size) noexcept -> void { - if (size) - { - } + (void)size; teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer); } @@ -75,8 +73,6 @@ auto operator delete[](void * pointer) noexcept -> void auto operator delete[](void * pointer, std::size_t size) noexcept -> void { - if (size) - { - } + (void)size; teachos::arch::memory::heap::global_heap_allocator::deallocate(pointer); } -- cgit v1.2.3 From 191e7ef3001e422c2f58efe7381d13932e1c1537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Mon, 24 Feb 2025 08:40:46 +0000 Subject: Add noexpect to deallocate calls --- arch/x86_64/include/arch/memory/heap/bump_allocator.hpp | 2 +- arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp | 2 +- arch/x86_64/include/arch/memory/heap/heap_allocator.hpp | 2 +- arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp | 2 +- arch/x86_64/src/memory/heap/bump_allocator.cpp | 2 +- arch/x86_64/src/memory/heap/global_heap_allocator.cpp | 2 +- arch/x86_64/src/memory/heap/linked_list_allocator.cpp | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/x86_64/include/arch/memory/heap/bump_allocator.hpp b/arch/x86_64/include/arch/memory/heap/bump_allocator.hpp index 74734af..011f45c 100644 --- a/arch/x86_64/include/arch/memory/heap/bump_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/bump_allocator.hpp @@ -35,7 +35,7 @@ namespace teachos::arch::memory::heap * * @note Simply does nothing, because this allocator leaks all memory */ - auto deallocate(void * pointer) -> void override; + auto deallocate(void * pointer) noexcept -> void override; private: std::size_t heap_start; ///< Start of the allocatable heap area diff --git a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp index a1621b5..dff837e 100644 --- a/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp @@ -53,7 +53,7 @@ namespace teachos::arch::memory::heap * * @param pointer Previously allocated memory area, that should now be freed */ - static auto deallocate(void * pointer) -> void; + static auto deallocate(void * pointer) noexcept -> void; private: static heap_allocator * allocator_instance; ///< Instance used to actually allocate and deallocate diff --git a/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp index 01657f2..6aed3d8 100644 --- a/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp @@ -36,7 +36,7 @@ namespace teachos::arch::memory::heap * * @param pointer Previously allocated memory area, that should now be freed */ - virtual auto deallocate(void * pointer) -> void = 0; + virtual auto deallocate(void * pointer) noexcept -> void = 0; }; } // namespace teachos::arch::memory::heap diff --git a/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp b/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp index d53756d..df9e370 100644 --- a/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp +++ b/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp @@ -35,7 +35,7 @@ namespace teachos::arch::memory::heap */ auto allocate(std::size_t size) -> void * override; - auto deallocate(void * pointer) -> void override; + auto deallocate(void * pointer) noexcept -> void override; private: /** diff --git a/arch/x86_64/src/memory/heap/bump_allocator.cpp b/arch/x86_64/src/memory/heap/bump_allocator.cpp index a9fb121..df95346 100644 --- a/arch/x86_64/src/memory/heap/bump_allocator.cpp +++ b/arch/x86_64/src/memory/heap/bump_allocator.cpp @@ -42,7 +42,7 @@ namespace teachos::arch::memory::heap } } - auto bump_allocator::deallocate(void * pointer) -> void + auto bump_allocator::deallocate(void * pointer) noexcept -> void { 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 index 235c544..c1ca160 100644 --- a/arch/x86_64/src/memory/heap/global_heap_allocator.cpp +++ b/arch/x86_64/src/memory/heap/global_heap_allocator.cpp @@ -10,7 +10,7 @@ namespace teachos::arch::memory::heap auto global_heap_allocator::allocate(std::size_t size) -> void * { return get().allocate(size); } - auto global_heap_allocator::deallocate(void * pointer) -> void { get().deallocate(pointer); } + 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 { 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 9beb466..a824c8a 100644 --- a/arch/x86_64/src/memory/heap/linked_list_allocator.cpp +++ b/arch/x86_64/src/memory/heap/linked_list_allocator.cpp @@ -59,7 +59,7 @@ namespace teachos::arch::memory::heap exception_handling::panic("[Linked List Allocator] Out of memory"); } - auto linked_list_allocator::deallocate(void * pointer) -> void + auto linked_list_allocator::deallocate(void * pointer) noexcept -> void { mutex.lock(); -- cgit v1.2.3 From b76fd5fcd04c7541c11c3d9c5b2edf1352d70c64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Mon, 24 Feb 2025 10:11:26 +0000 Subject: Enable run time and compile time sanitizers to catch more errors --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 12ac210..7d30a2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,7 @@ add_compile_options( "$<$:-Wextra>" "$<$:-Werror>" "$<$:-pedantic-errors>" + "$<$:-fsanitize=address,leak,bounds,alignment,return,integer-divide-by-zero,vla-bound,null,enum,pointer-overflow>" ) #[============================================================================[ -- cgit v1.2.3 From 2cbaf2d52bd9379e5c6e4a0d018b25d1c882193d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Tue, 25 Feb 2025 14:41:03 +0000 Subject: Create inital custom version of c++ vector --- CMakeLists.txt | 8 ++ arch/x86_64/CMakeLists.txt | 7 ++ arch/x86_64/include/arch/stl/vector.hpp | 193 ++++++++++++++++++++++++++++++++ 3 files changed, 208 insertions(+) create mode 100644 arch/x86_64/include/arch/stl/vector.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d30a2c..8657cab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,6 +115,13 @@ add_library("teachos::memory" ALIAS "_memory") add_library("_exception" OBJECT) add_library("teachos::exception" ALIAS "_exception") +#[============================================================================[ +# The Shared Library +#]============================================================================] + +add_library("_shared" OBJECT) +add_library("teachos::shared" ALIAS "_shared") + #[============================================================================[ # The Kernel #]============================================================================] @@ -129,6 +136,7 @@ target_link_libraries("_kernel" PRIVATE "teachos::video" "teachos::memory" "teachos::exception" + "teachos::shared" ) #[============================================================================[ diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt index 9665846..e9f8d5f 100644 --- a/arch/x86_64/CMakeLists.txt +++ b/arch/x86_64/CMakeLists.txt @@ -60,6 +60,13 @@ target_sources("_memory" PRIVATE "src/memory/heap/memory_block.cpp" "src/memory/heap/linked_list_allocator.cpp" "src/memory/heap/global_heap_allocator.cpp" +) + +#[============================================================================[ +# The Shared Library +#]============================================================================] + +target_sources("_shared" PRIVATE "src/shared/mutex.cpp" ) diff --git a/arch/x86_64/include/arch/stl/vector.hpp b/arch/x86_64/include/arch/stl/vector.hpp new file mode 100644 index 0000000..62be704 --- /dev/null +++ b/arch/x86_64/include/arch/stl/vector.hpp @@ -0,0 +1,193 @@ +#ifndef TEACHOS_ARCH_X86_64_STL_VECTOR_HPP +#define TEACHOS_ARCH_X86_64_STL_VECTOR_HPP + +#include "arch/exception_handling/panic.hpp" +#include "arch/shared/container.hpp" +#include "arch/shared/contiguous_pointer_iterator.hpp" + +#include + +namespace teachos::arch::stl +{ + /** + * @brief Custom vector implementation mirroring the std::vector to allow for the usage of STL functionality with our + * custom memory management + * + * @tparam T Element the vector instance should contain + */ + template + struct vector + { + /** + * @brief Defaulted constructor. Initalizes empty vector + */ + vector() = default; + + /** + * @brief Constructs data with the given amount of elements containg the given value or alterantively the default + * constructed value + * + * @param capacity Amount of elements we want to create and set the given value for + * @param initial Inital value of all elements in the underlying data array + */ + vector(size_t capacity, T initial = T{}) + : capacity(capacity) + , size(capacity) + , data(new T[capacity]{}) + { + auto const begin = data; + auto const end = data + size; + vector_container container{begin, end}; + std::ranges::fill(container, inital); + } + + /** + * @brief Copy constructor + * + * @note Allocates underlying data container with the same capacity as vector we are copying from and copies all + * elements from it + * + * @param other Other instance of vector we want to copy the data from + */ + vector(vector const & other) + : size(size) + , capacity(capacity) + { + delete[] data; + data = new T[capacity]{}; + + auto const begin = other.data; + auto const end = other.data + size; + vector_container container{begin, end}; + std::ranges::copy(container, data); + } + + /** + * @brief Copy assignment operator + * + * @note Allocates underlying data container with the same capacity as vector we are copying from and copies all + * elements from it + * + * @param other Other instance of vector we want to copy the data from + * @return Newly created copy + */ + vector & operator=(vector const & other) + { + delete[] data; + size = other.size(); + capacity = other.capacity(); + data = new T[capacity]{}; + + auto const begin = other.data; + auto const end = other.data + size; + vector_container container{begin, end}; + std::ranges::copy(container, data); + return *this; + } + + /** + * @brief Destructor + */ + ~vector() { delete[] data; } + + /** + * @brief Amount of elements currently contained in this vector, will fill up until we have reached the capacity. If + * that is the case the capacity is increased automatically + * + * @return Current amount of elements + */ + size_t size() const { return size; } + + /** + * @brief Amount of space the vector currently has, can be different than the size, because we allocate more than we + * exactly require to decrease the amount of allocations and deallocation to improve speed + * + * @return Current amount of space the vector has for elements + */ + size_t capacity() const { return capacity; } + + /** + * @brief Array indexing operator. Allowing to access element at the given index + * + * @note Does not do any bounds checks use at() for that + * + * @param index Index we want to access elements at + * @return Reference to the underlying element + */ + T & operator[](size_t index) { return data[index]; } + + /** + * @brief Array indexing operator. Allowing to access element at the given index + * + * @note Ensures we do not access element outside of the bounds of the array, if we do further execution is halted + * + * @param index Index we want to access elements at + * @return Reference to the underlying element + */ + T & at(size_t index) + { + if (index >= size) + { + exception_handling::panic("[Vector] Attempted to read element at invalid index"); + } + return this->operator[](size); + } + + void push_back(T & const element) {} + + void emplace_back(T && const element) + { + // If no cacacity, increase capacity + if (size == capacity) + { + reserve(capacity * 2); + } + + data[size] = element; + size++; + } + + void pop_back() + { + if (size <= 0) + { + exception_handling::panic("[Vector] Attempted to pop back last element of already empty vector"); + } + size--; + } + + T & front() { return *data; } + + T & back() { return *(data + size); } + + void reserve(size_t new_capacity) + { + if (new_capacity < size) + { + // Creating new array with less capacity than is required to keep all current elements makes no sense + return; + } + + T * temp = new T[new_capacity]; + + auto const begin = other.data; + auto const end = other.data + capacity; + vector_container container{begin, end}; + std::ranges::copy(container, temp); + + delete[] data; + capacity = new_capacity; + data = temp; + } + + private: + T * data = {}; ///< Pointer to the first element in the underlying data container + size_t capacity = {}; ///< Amount of space for elements in the underlying data container + size_t size = {}; ///< Amount of elements in the underlying data container + + typedef shared::container> vector_container; + }; + +} // namespace teachos::arch::stl + +#endif // TEACHOS_ARCH_X86_64_STL_VECTOR_HPP -- cgit v1.2.3 From 462a4e09b1a67562dd1a122936c1ad0fc1771e0e Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 27 Feb 2025 07:15:03 +0000 Subject: add smart pointers --- arch/x86_64/include/arch/stl/shared_pointer.hpp | 120 ++++++++++++++++++++++++ arch/x86_64/include/arch/stl/unique_pointer.hpp | 68 ++++++++++++++ 2 files changed, 188 insertions(+) create mode 100644 arch/x86_64/include/arch/stl/shared_pointer.hpp create mode 100644 arch/x86_64/include/arch/stl/unique_pointer.hpp diff --git a/arch/x86_64/include/arch/stl/shared_pointer.hpp b/arch/x86_64/include/arch/stl/shared_pointer.hpp new file mode 100644 index 0000000..79a9f82 --- /dev/null +++ b/arch/x86_64/include/arch/stl/shared_pointer.hpp @@ -0,0 +1,120 @@ +#ifndef TEACHOS_ARCH_X86_64_STL_SHARED_POINTER_HPP +#define TEACHOS_ARCH_X86_64_STL_SHARED_POINTER_HPP + +namespace teachos::arch::stl +{ + template + struct shared_pointer + { + explicit shared_pointer(T * pointer = nullptr) + : pointer(pointer) + , ref_count(new std::atomic(pointer != nullptr ? 1 : 0)) + { + } + + shared_pointer(const shared_pointer & other) + : pointer(other.pointer) + , ref_count(other.ref_count) + { + if (pointer != nullptr) + { + ++(*ref_count); + } + } + + shared_pointer(shared_pointer && other) noexcept + : pointer(other.pointer) + , ref_count(other.ref_count) + { + other.pointer = nullptr; + other.ref_count = nullptr; + } + + shared_pointer & operator=(const shared_pointer & other) + { + if (this != &other) + { + cleanup(); + pointer = other.pointer; + ref_count = other.ref_count; + + if (pointer != nullptr) + { + ++(*ref_count); + } + } + + return *this; + } + + shared_pointer & operator=(shared_pointer && other) noexcept + { + if (this != &other) + { + cleanup(); + pointer = other.pointer; + ref_count = other.ref_count; + other.pointer = nullptr; + other.ref_count = nullptr; + } + + return *this; + } + + ~shared_pointer() { cleanup(); } + + void cleanup() + { + if (pointer != nullptr && ref_count != nullptr && --(*ref_count) == 0) + { + delete pointer; + delete ref_count; + } + } + + void reset(T * p = nullptr) + { + cleanup(); + pointer = p; + ref_count = new std::atomic(p != nullptr ? 1 : 0); + } + + void swap(shared_pointer & other) + { + std::swap(pointer, other.pointer); + std::swap(ref_count, other.ref_count); + } + + T & operator*() const { return *pointer; } + + T * operator->() const { return pointer; } + + T * get() const { return pointer; } + + int use_count() const + { + if (pointer != nullptr) + { + return *ref_count; + } + + return 0; + } + + bool unique() const { return use_count() == 1; } + + explicit operator bool() const { return pointer != nullptr; } + + private: + T * pointer; + std::atomic * ref_count; + }; + + template + shared_pointer make_shared(Args &&... args) + { + return shared_pointer(new T(std::forward(args)...)); + } +} // namespace teachos::arch::stl + +#endif // TEACHOS_ARCH_X86_64_STL_SHARED_POINTER_HPP \ No newline at end of file diff --git a/arch/x86_64/include/arch/stl/unique_pointer.hpp b/arch/x86_64/include/arch/stl/unique_pointer.hpp new file mode 100644 index 0000000..0ec3c38 --- /dev/null +++ b/arch/x86_64/include/arch/stl/unique_pointer.hpp @@ -0,0 +1,68 @@ +#ifndef TEACHOS_ARCH_X86_64_STL_UNIQUE_POINTER_HPP +#define TEACHOS_ARCH_X86_64_STL_UNIQUE_POINTER_HPP + +namespace teachos::arch::stl +{ + template + struct unique_pointer + { + explicit unique_pointer(T * ptr = nullptr) + : pointer(ptr) + { + } + + ~unique_pointer() { delete pointer; } + + unique_pointer(const unique_pointer &) = delete; + unique_pointer & operator=(const unique_pointer &) = delete; + + unique_pointer(unique_pointer && other) noexcept + : pointer(other.pointer) + { + other.pointer = nullptr; + } + + unique_pointer & operator=(unique_pointer && other) noexcept + { + if (this != &other) + { + delete pointer; + pointer = other.pointer; + other.pointer = nullptr; + } + return *this; + } + + T & operator*() const { return *pointer; } + + T * operator->() const { return pointer; } + + T * get() const { return pointer; } + + T * release() + { + T * temp = pointer; + pointer = nullptr; + return temp; + } + + void reset(T * ptr = nullptr) + { + delete pointer; + pointer = ptr; + } + + void swap(unique_pointer & other) { std::swap(pointer, other.pointer); } + + private: + T * pointer; + }; + + template + unique_pointer make_unique(Args &&... args) + { + return unique_pointer(new T(std::forward(args)...)); + } +} // namespace teachos::arch::stl + +#endif // TEACHOS_ARCH_X86_64_STL_UNIQUE_POINTER_HPP \ No newline at end of file -- cgit v1.2.3 From dc86ba14f5d9cae44f9922f7a9627369e4a3172e Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 27 Feb 2025 07:49:38 +0000 Subject: remove interrupt.hpp --- arch/x86_64/include/arch/kernel/interrupt.hpp | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 arch/x86_64/include/arch/kernel/interrupt.hpp diff --git a/arch/x86_64/include/arch/kernel/interrupt.hpp b/arch/x86_64/include/arch/kernel/interrupt.hpp deleted file mode 100644 index 521318d..0000000 --- a/arch/x86_64/include/arch/kernel/interrupt.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_KERNEL_INTERRUPT_HPP -#define TEACHOS_ARCH_X86_64_KERNEL_INTERRUPT_HPP - -#include - -namespace teachos::arch::kernel -{ - struct stack_frame - { - std::uint16_t instruction_pointer; - std::uint16_t cs; - std::uint16_t flags; - std::uint16_t sp; - std::uint16_t ss; - }; - - /** - * @brief Handles an interrupt - * - * https://clang.llvm.org/docs/AttributeReference.html#interrupt-x86 - */ - __attribute__((interrupt)) extern "C" auto interrupt_handler(struct stack_frame * frame) -> void; - -} // namespace teachos::arch::kernel - -#endif // TEACHOS_ARCH_X86_64_KERNEL_INTERRUPT_HPP -- cgit v1.2.3 From 2f1f0fa8b0dc1893219be68ab8bf653b5d6349fb Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 27 Feb 2025 07:58:01 +0000 Subject: clear interrupt flag --- arch/x86_64/src/boot/boot.s | 2 ++ 1 file changed, 2 insertions(+) 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 -- cgit v1.2.3