diff options
11 files changed, 0 insertions, 1122 deletions
diff --git a/arch/x86_64/pre/include/arch/memory/heap/bump_allocator.hpp b/arch/x86_64/pre/include/arch/memory/heap/bump_allocator.hpp deleted file mode 100644 index 011f45c..0000000 --- a/arch/x86_64/pre/include/arch/memory/heap/bump_allocator.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#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 <atomic> -#include <cstdint> - -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 : heap_allocator - { - /** - * @brief Constructor. - * - * @param heap_start Start of the allocatable heap area - * @param heap_end End of the allocatable heap area (Start + Size) - */ - bump_allocator(std::size_t heap_start, std::size_t heap_end) - : heap_start{heap_start} - , heap_end{heap_end} - , next{heap_start} - { - // Nothing to do - } - - auto allocate(std::size_t size) -> void * override; - - /** - * @copybrief heap_allocator::deallocate - * - * @note Simply does nothing, because this allocator leaks all memory - */ - auto deallocate(void * pointer) noexcept -> void override; - - private: - std::size_t heap_start; ///< Start of the allocatable heap area - std::size_t heap_end; ///< End of the allocatable heap area - std::atomic_uint64_t next; ///< Current address, which is the start of still unused allocatable heap area - }; - -} // namespace teachos::arch::memory::heap - -#endif // TEACHOS_ARCH_X86_64_MEMORY_HEAP_BUMP_ALLOCATOR_HPP diff --git a/arch/x86_64/pre/include/arch/memory/heap/global_heap_allocator.hpp b/arch/x86_64/pre/include/arch/memory/heap/global_heap_allocator.hpp deleted file mode 100644 index 480b1d0..0000000 --- a/arch/x86_64/pre/include/arch/memory/heap/global_heap_allocator.hpp +++ /dev/null @@ -1,117 +0,0 @@ -#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/heap_allocator.hpp" -#include "arch/memory/heap/user_heap_allocator.hpp" - -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, ///< 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 - }; - - /** - * @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 - */ - auto static 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 - */ - auto static kmalloc(std::size_t size) -> void *; - - /** - * @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 - */ - auto static kfree(void * pointer) noexcept -> 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 - */ - [[gnu::section(".user_text")]] - auto static malloc(std::size_t size) -> void *; - - /** - * @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 - */ - [[gnu::section(".user_text")]] - auto static free(void * pointer) noexcept -> void; - - private: - heap_allocator static * kernel_allocator_instance; ///< Instance used to allocate and deallocate kernel heap memory - [[gnu::section(".user_data")]] user_heap_allocator static * - user_allocator_instance; ///< Instance used to allocate and deallocate user heap memory - - /** - * @brief Either returns the previously registered heap allocated or halts further execution - * - * @return Reference to the registered kernel heap allocation - */ - auto static kernel() -> heap_allocator &; - - /** - * @brief Either returns the previously registered heap allocated or halts further execution - * - * @return Reference to the registered user heap allocation - */ - [[gnu::section(".user_text")]] auto static user() -> user_heap_allocator &; - }; -} // namespace teachos::arch::memory::heap - -[[gnu::section(".user_text")]] -auto operator new(std::size_t size) -> void *; - -[[gnu::section(".user_text")]] -auto operator delete(void * pointer) noexcept -> void; - -[[gnu::section(".user_text")]] -auto operator delete(void * pointer, std::size_t size) noexcept -> void; - -[[gnu::section(".user_text")]] -auto operator new[](std::size_t size) -> void *; - -[[gnu::section(".user_text")]] -auto operator delete[](void * pointer) noexcept -> void; - -[[gnu::section(".user_text")]] -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/pre/include/arch/memory/heap/heap_allocator.hpp b/arch/x86_64/pre/include/arch/memory/heap/heap_allocator.hpp deleted file mode 100644 index 6c25532..0000000 --- a/arch/x86_64/pre/include/arch/memory/heap/heap_allocator.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_MEMORY_HEAP_HEAP_ALLOCATOR_HPP -#define TEACHOS_ARCH_X86_64_MEMORY_HEAP_HEAP_ALLOCATOR_HPP - -#include <cstdint> - -namespace teachos::arch::memory::heap -{ - constexpr std::size_t KERNEL_HEAP_START = 0x1'0000'0000; - constexpr std::size_t KERNEL_HEAP_SIZE = 100 * 1024; - constexpr std::size_t USER_HEAP_START = 0x1'0001'9000; // Starts directly after kernel heap - constexpr std::size_t USER_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 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 - */ - virtual auto deallocate(void * pointer) noexcept -> void = 0; - }; -} // namespace teachos::arch::memory::heap - -#endif // TEACHOS_ARCH_X86_64_MEMORY_HEAP_HEAP_ALLOCATOR_HPP diff --git a/arch/x86_64/pre/include/arch/memory/heap/linked_list_allocator.hpp b/arch/x86_64/pre/include/arch/memory/heap/linked_list_allocator.hpp deleted file mode 100644 index bb8b526..0000000 --- a/arch/x86_64/pre/include/arch/memory/heap/linked_list_allocator.hpp +++ /dev/null @@ -1,123 +0,0 @@ -#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 <kstd/mutex.hpp> - -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 : heap_allocator - { - /** - * @brief Constructor. - * - * @param heap_start Start of the allocatable heap area - * @param heap_end End of the allocatable heap area (Start + Size) - */ - linked_list_allocator(std::size_t heap_start, std::size_t heap_end); - - /** - * @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 - * and alteast enough memory for another free memory block entry (16 bytes). If the amount of memory of that free - * memory block is in between we cannot use it for our allocation, because we could only return it to the user, but - * the additional bytes, could not be used to create a free memory block. Additionaly the user couldn't know - * 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. - */ - auto allocate(std::size_t size) -> void * override; - - auto deallocate(void * pointer) noexcept -> void override; - - private: - /** - * @brief Returns the smallest allocatable block of heap memory. - * - * @return Smallest allocatable block of heap memory. - */ - constexpr auto min_allocatable_size() -> std::size_t - { - return sizeof(memory_block); - } - - /** - * @brief Removes a free memory block from the free list and returns its address so the caller can allocate into it. - * - * @param previous_block Free memory block before the block to allocate in our heap memory. Was to small to - * allocate the required size into. - * @param current_block Free memory block we want to remove from the free list and return for the allocation. - * - * @return Previous start address of the memory block we removed, because it can now be used for the allocation. - */ - auto remove_free_memory_block(memory_block * previous_block, memory_block * current_block) -> void *; - - /** - * @brief Splits the given free memory block into two, where the latter block keeps being free and the first - * part will be used for the allocation. - * - * @param previous_block Free memory block before the block to allocate in our heap memory. Was to small to - * allocate the required size into. - * @param current_block Free memory block we want to split into a size part for the allocation and the rest for - * future allocations. - * @param size Size we want to allocate at the start of the free memory block. - * - * @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 *; - - /** - * @brief Removes a free memory block from the free list and returns its address so the caller can allocate into it. - * - * @param previous_block Free memory block before the block to allocate in our heap memory. Was to small to - * allocate the required size into. - * @param current_block Free memory block we want to remove from the free list and return for the allocation. - * @param new_block Replaces the current block with the given new block can be nullptr, meaning the free list will - * end here. - * - * @return Previous start address of the memory block we removed, because it can now be used for the allocation. - */ - auto replace_free_memory_block(memory_block * previous_block, memory_block * current_block, - memory_block * new_block) -> void *; - - /** - * @brief Combines multiple free memory blocks into one if they are adjacent. - * - * @note The internal algorithm for recombination functions like this: - * 1. Check if there is even any memory left, if not the first entry of our linked list should be a nullptr and - * we can therefore set the first entry to our newly created entry. This entry is created in the now deallocated - * memory area. - * 2. If there are more blocks but neither the previous nor the current block are adjacent, we simply create a - * new free memory block of the given size and set the previous next to our block and the next of our block to - * the current block. - * 3. If the current block is adjacent the start address of the newly created block stays the same, but the size - * increases by the amount in the current memory block header. After reading it we also clear the header. - * 4. If the previous block is adjacent the size of the previous block simply increases to include the given - * size as well. - * 5. If the previous block is directly in our start address, so they overlap then it has to mean some or all of - * the region we are trying to deallocate has been freed before. Which would result in a double free therefore - * we halt the execution of the program. - * - * @param previous_block Free memory block before the block to deallocate in our heap memory. - * @param current_block Free memory block after the block to deallocate in our heap memory. - * @param pointer Block to deallocate. - * @param size Size of the block we want to deallocate. - */ - auto coalesce_free_memory_block(memory_block * previous_block, memory_block * current_block, void * pointer, - std::size_t size) -> void; - - memory_block * first; ///< First free entry in our memory. - kstd::mutex mutex; ///< Mutex to ensure only one thread calls allocate or deallocate at once. - }; -} // namespace teachos::arch::memory::heap - -#endif // TEACHOS_ARCH_X86_64_MEMORY_HEAP_LINKED_LIST_ALLOCATOR_HPP diff --git a/arch/x86_64/pre/include/arch/memory/heap/memory_block.hpp b/arch/x86_64/pre/include/arch/memory/heap/memory_block.hpp deleted file mode 100644 index 9d1fb02..0000000 --- a/arch/x86_64/pre/include/arch/memory/heap/memory_block.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_MEMORY_HEAP_MEMORY_BLOCK_HPP -#define TEACHOS_ARCH_X86_64_MEMORY_HEAP_MEMORY_BLOCK_HPP - -#include <cstdint> - -namespace teachos::arch::memory::heap -{ - /** - * @brief Block containing free memory, pointing to the next free hole (nullptr) if there is none. - * Forms a singly linked list of free memory blocks that we can callocate memory into. - */ - struct memory_block - { - /** - * @brief Constructor. Clears all memory from the place it was allocated until the end (address + - * size). - * - * @param size Amount of free memory of this specific hole. - * @param next Optional pointer to the next free memory. - */ - [[gnu::section(".user_text")]] - memory_block(std::size_t size, memory_block * next); - - /** - * @brief Destructor. Clears all internal memory. - * - * @note Used so the memory can be reused to construct other classes into, without having the old values. - * Required because we cannot call delete, because it causes "undefined reference to `sbrk`". - */ - [[gnu::section(".user_text")]] - ~memory_block(); - - std::size_t size; ///< Amount of free memory this hole contains, has to always be atleast 16 bytes to hold the - ///< 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/pre/include/arch/memory/heap/user_heap_allocator.hpp b/arch/x86_64/pre/include/arch/memory/heap/user_heap_allocator.hpp deleted file mode 100644 index 15d8574..0000000 --- a/arch/x86_64/pre/include/arch/memory/heap/user_heap_allocator.hpp +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_MEMORY_HEAP_USER_HEAP_ALLOCATOR_HPP -#define TEACHOS_ARCH_X86_64_MEMORY_HEAP_USER_HEAP_ALLOCATOR_HPP - -#include "arch/memory/heap/memory_block.hpp" - -// #include <kstd/mutex.hpp> -#include <kstd/mutex.hpp> - -#include <optional> - -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 user_heap_allocator - { - /** - * @brief Constructor. - */ - user_heap_allocator() = default; - - /** - * @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 - * and alteast enough memory for another free memory block entry (16 bytes). If the amount of memory of that free - * memory block is in between we cannot use it for our allocation, because we could only return it to the user, but - * the additional bytes, could not be used to create a free memory block. Additionaly the user couldn't know - * 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. - */ - [[gnu::section(".user_text")]] - auto allocate(std::size_t size) -> void *; - - /** - * @copybrief heap_allocator::deallocate - */ - [[gnu::section(".user_text")]] - auto deallocate(void * pointer) noexcept -> void; - - private: - /** - * @brief Returns the smallest allocatable block of heap memory. - * - * @return Smallest allocatable block of heap memory. - */ - [[gnu::section(".user_text")]] constexpr auto min_allocatable_size() -> std::size_t - { - return sizeof(memory_block); - } - - /** - * @brief Checks if the given memory block is big enough and if it is allocates into the current block. - * - * @note Adjusts the link of the previous memory block to the new smaller remaining block. If the allocation used - * the complete block instead the previous block will point to the next block of the current memroy block that was - * used for the allocation. - * - * @return Allocated usable memory area. - */ - [[gnu::section(".user_text")]] auto - allocate_into_memory_block_if_big_enough(memory_block * current, memory_block * previous, std::size_t total_size) - -> std::optional<void *>; - - /** - * @brief Special functionality fo the user heap allocator. Which will result in it being expanded by a syscall with - * addtionally 100 KiB, which are mapped into the page table. Will always work until there is no physical memory - * left. - * - * @return Start of the newly with syscall allocated free memory block. Nullptr if the syscall failed. - */ - [[gnu::section(".user_text")]] auto expand_heap_if_full() -> memory_block *; - - /** - * @brief Removes a free memory block from the free list and returns its address so the caller can allocate into it. - * - * @param previous_block Free memory block before the block to allocate in our heap memory. Was to small to - * allocate the required size into. - * @param current_block Free memory block we want to remove from the free list and return for the allocation. - * - * @return Previous start address of the memory block we removed, because it can now be used for the allocation. - */ - [[gnu::section(".user_text")]] - auto remove_free_memory_block(memory_block * previous_block, memory_block * current_block) -> void *; - - /** - * @brief Splits the given free memory block into two, where the latter block keeps being free and the first - * part will be used for the allocation. - * - * @param previous_block Free memory block before the block to allocate in our heap memory. Was to small to - * allocate the required size into. - * @param current_block Free memory block we want to split into a size part for the allocation and the rest for - * future allocations. - * @param size Size we want to allocate at the start of the free memory block. - * - * @return Previous start address of the memory block we just split, because it can now be used for the allocation. - */ - [[gnu::section(".user_text")]] - 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. - * - * @param previous_block Free memory block before the block to allocate in our heap memory. Was to small to - * allocate the required size into. - * @param current_block Free memory block we want to remove from the free list and return for the allocation. - * @param new_block Replaces the current block with the given new block can be nullptr, meaning the free list will - * end here. - * - * @return Previous start address of the memory block we removed, because it can now be used for the allocation. - */ - [[gnu::section(".user_text")]] - auto replace_free_memory_block(memory_block * previous_block, memory_block * current_block, - memory_block * new_block) -> void *; - - /** - * @brief Combines multiple free memory blocks into one if they are adjacent. - * - * @note The internal algorithm for recombination functions like this: - * 1. Check if there is even any memory left, if not the first entry of our linked list should be a nullptr and - * we can therefore set the first entry to our newly created entry. This entry is created in the now deallocated - * memory area. - * 2. If there are more blocks but neither the previous nor the current block are adjacent, we simply create a - * new free memory block of the given size and set the previous next to our block and the next of our block to - * the current block. - * 3. If the current block is adjacent the start address of the newly created block stays the same, but the size - * increases by the amount in the current memory block header. After reading it we also clear the header. - * 4. If the previous block is adjacent the size of the previous block simply increases to include the given - * size as well. - * 5. If the previous block is directly in our start address, so they overlap then it has to mean some or all of - * the region we are trying to deallocate has been freed before. Which would result in a double free therefore - * we halt the execution of the program. - * - * @param previous_block Free memory block before the block to deallocate in our heap memory. - * @param current_block Free memory block after the block to deallocate in our heap memory. - * @param pointer Block to deallocate. - * @param size Size of the block we want to deallocate. - */ - [[gnu::section(".user_text")]] - auto coalesce_free_memory_block(memory_block * previous_block, memory_block * current_block, void * pointer, - std::size_t size) -> void; - - memory_block * first = {}; ///< First free entry in our memory. - kstd::mutex mutex = {}; ///< Mutex to ensure only one thread calls allocate or deallocate at once. - }; -} // namespace teachos::arch::memory::heap - -#endif // TEACHOS_ARCH_X86_64_MEMORY_HEAP_USER_HEAP_ALLOCATOR_HPP diff --git a/arch/x86_64/pre/src/memory/heap/bump_allocator.cpp b/arch/x86_64/pre/src/memory/heap/bump_allocator.cpp deleted file mode 100644 index 525f45c..0000000 --- a/arch/x86_64/pre/src/memory/heap/bump_allocator.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "arch/memory/heap/bump_allocator.hpp" - -#include "arch/exception_handling/assert.hpp" - -#include <limits> -#include <type_traits> - -namespace teachos::arch::memory::heap -{ - namespace - { - template<typename T> - auto saturating_add(T x, T y) -> T - requires std::is_unsigned_v<T> - { - if (x > std::numeric_limits<T>::max() - y) - { - return std::numeric_limits<T>::max(); - } - T result = x + y; - return result; - } - } // namespace - - auto bump_allocator::allocate(std::size_t size) -> void * - { - // Reading the value only has to be done once, because compare_exchange_weak updates the value as well if the - // exchange failed, becuase the value was not the expected one. - auto alloc_start = next.load(std::memory_order::relaxed); - // Repeat allocation until it succeeds, has to be done, because another allocator could overtake it at any time - // causing the value to differ and the calculation to have to be redone. - for (;;) - { - auto const alloc_end = saturating_add(alloc_start, size); - arch::exception_handling::assert(alloc_end <= heap_end, "[Heap Allocator] Out of memory"); - // Check if the atomic value is still the one initally loaded, if it isn't we have been overtaken by another - // thread and need to redo the calculation. Spurious failure by weak can be ignored, because the whole allocation - // is wrapped in an infinite for loop so a failure that wasn't actually one will simply be retried until it works. - auto const updated = next.compare_exchange_weak(alloc_start, alloc_end, std::memory_order::relaxed); - if (updated) - { - return reinterpret_cast<void *>(alloc_start); - } - } - } - - auto bump_allocator::deallocate(void * pointer) noexcept -> void - { - if (pointer) - { - } - } - -} // namespace teachos::arch::memory::heap diff --git a/arch/x86_64/pre/src/memory/heap/global_heap_allocator.cpp b/arch/x86_64/pre/src/memory/heap/global_heap_allocator.cpp deleted file mode 100644 index 709cda1..0000000 --- a/arch/x86_64/pre/src/memory/heap/global_heap_allocator.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#include "arch/memory/heap/global_heap_allocator.hpp" - -#include "arch/context_switching/syscall/main.hpp" -#include "arch/exception_handling/assert.hpp" -#include "arch/kernel/cpu/segment_register.hpp" -#include "arch/memory/heap/bump_allocator.hpp" -#include "arch/memory/heap/linked_list_allocator.hpp" -#include "arch/memory/heap/user_heap_allocator.hpp" - -namespace teachos::arch::memory::heap -{ - namespace - { - constexpr char NOT_REGISTRED_ERROR_MESSAGE[] = - "Attempted to allocate or deallocate using the global_heap_allocator before " - "register_heap_allocation_type was called."; - constexpr uint16_t KERNEL_CODE_INDEX = 1U; - - [[gnu::section(".user_text")]] - auto os_in_kernel_mode() -> bool - { - auto const cs = teachos::arch::kernel::cpu::read_code_segment_register(); - return cs.get_index() == KERNEL_CODE_INDEX; - } - } // namespace - - heap_allocator * global_heap_allocator::kernel_allocator_instance = nullptr; - user_heap_allocator * global_heap_allocator::user_allocator_instance = nullptr; - - auto global_heap_allocator::kmalloc(std::size_t size) -> void * - { - return kernel().allocate(size); - } - - auto global_heap_allocator::kfree(void * pointer) noexcept -> void - { - kernel().deallocate(pointer); - } - - auto global_heap_allocator::malloc(std::size_t size) -> void * - { - return user().allocate(size); - } - - auto global_heap_allocator::free(void * pointer) noexcept -> void - { - user().deallocate(pointer); - } - - auto global_heap_allocator::register_heap_allocator(heap_allocator_type new_type) -> void - { - exception_handling::assert(kernel_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: - { - bump_allocator static kernel_allocator{KERNEL_HEAP_START, KERNEL_HEAP_START + KERNEL_HEAP_SIZE}; - kernel_allocator_instance = &kernel_allocator; - break; - } - case heap_allocator_type::LINKED_LIST: - { - linked_list_allocator static kernel_allocator{KERNEL_HEAP_START, KERNEL_HEAP_START + KERNEL_HEAP_SIZE}; - kernel_allocator_instance = &kernel_allocator; - break; - } - } - - [[gnu::section(".user_data")]] user_heap_allocator static user_allocator{}; - user_allocator_instance = &user_allocator; - } - - auto global_heap_allocator::kernel() -> heap_allocator & - { - exception_handling::assert(kernel_allocator_instance != nullptr, NOT_REGISTRED_ERROR_MESSAGE); - - return *kernel_allocator_instance; - } - - auto global_heap_allocator::user() -> user_heap_allocator & - { - context_switching::syscall::syscall( - context_switching::syscall::type::ASSERT, - {user_allocator_instance != nullptr, reinterpret_cast<uint64_t>(&NOT_REGISTRED_ERROR_MESSAGE)}); - return *user_allocator_instance; - } -} // namespace teachos::arch::memory::heap - -auto operator new(std::size_t size) -> void * -{ - if (teachos::arch::memory::heap::os_in_kernel_mode()) - { - return teachos::arch::memory::heap::global_heap_allocator::kmalloc(size); - } - return teachos::arch::memory::heap::global_heap_allocator::malloc(size); -} - -auto operator delete(void * pointer) noexcept -> void -{ - if (teachos::arch::memory::heap::os_in_kernel_mode()) - { - teachos::arch::memory::heap::global_heap_allocator::kfree(pointer); - } - teachos::arch::memory::heap::global_heap_allocator::free(pointer); -} - -auto operator delete(void * pointer, std::size_t size) noexcept -> void -{ - (void)size; - if (teachos::arch::memory::heap::os_in_kernel_mode()) - { - teachos::arch::memory::heap::global_heap_allocator::kfree(pointer); - } - teachos::arch::memory::heap::global_heap_allocator::free(pointer); -} - -auto operator new[](std::size_t size) -> void * -{ - if (teachos::arch::memory::heap::os_in_kernel_mode()) - { - return teachos::arch::memory::heap::global_heap_allocator::kmalloc(size); - } - return teachos::arch::memory::heap::global_heap_allocator::malloc(size); -} - -auto operator delete[](void * pointer) noexcept -> void -{ - if (teachos::arch::memory::heap::os_in_kernel_mode()) - { - teachos::arch::memory::heap::global_heap_allocator::kfree(pointer); - } - teachos::arch::memory::heap::global_heap_allocator::free(pointer); -} - -auto operator delete[](void * pointer, std::size_t size) noexcept -> void -{ - (void)size; - if (teachos::arch::memory::heap::os_in_kernel_mode()) - { - teachos::arch::memory::heap::global_heap_allocator::kfree(pointer); - } - teachos::arch::memory::heap::global_heap_allocator::free(pointer); -} diff --git a/arch/x86_64/pre/src/memory/heap/linked_list_allocator.cpp b/arch/x86_64/pre/src/memory/heap/linked_list_allocator.cpp deleted file mode 100644 index 00ca366..0000000 --- a/arch/x86_64/pre/src/memory/heap/linked_list_allocator.cpp +++ /dev/null @@ -1,177 +0,0 @@ -#include "arch/memory/heap/linked_list_allocator.hpp" - -#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) - : first(nullptr) - , mutex{kstd::mutex{}} - { - auto const heap_size = heap_end - heap_start; - exception_handling::assert( - heap_size > min_allocatable_size(), - "[Linked List Allocator] Total heap size can not be smaller than minimum of 16 bytes to hold " - "atleast one memory hole entry"); - first = new (reinterpret_cast<void *>(heap_start)) memory_block(heap_size, nullptr); - } - - auto linked_list_allocator::allocate(std::size_t size) -> void * - { - // 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; - auto current = first; - - while (current != nullptr) - { - if (current->size == total_size) - { - auto const memory_address = remove_free_memory_block(previous, current); - new (memory_address) std::size_t(total_size); - mutex.unlock(); - return reinterpret_cast<void *>(reinterpret_cast<std::size_t>(memory_address) + sizeof(std::size_t)); - } - else if (current->size >= total_size + min_allocatable_size()) - { - // Ensure that the allocated size block is atleast 16 bytes (required because if we f |
