diff options
| author | Fabian Imhof <fabian.imhof@ost.ch> | 2025-02-27 09:21:43 +0100 |
|---|---|---|
| committer | Fabian Imhof <fabian.imhof@ost.ch> | 2025-02-27 09:21:43 +0100 |
| commit | 3fb836101a2032e93f7b82c924ce208d7377a5ea (patch) | |
| tree | 52f9aa1f5316b9938e74f43637c0641803fda01a | |
| parent | cd42c21f2460751428b3e1b4ae07ea0b924967bc (diff) | |
| parent | 2f1f0fa8b0dc1893219be68ab8bf653b5d6349fb (diff) | |
| download | teachos-3fb836101a2032e93f7b82c924ce208d7377a5ea.tar.xz teachos-3fb836101a2032e93f7b82c924ce208d7377a5ea.zip | |
Merge branch 'feat_new_delete_override' into 'develop_ba'
new delete override
See merge request teachos/kernel!4
19 files changed, 662 insertions, 99 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 12ac210..8657cab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,7 @@ add_compile_options( "$<$<CXX_COMPILER_ID:GNU>:-Wextra>" "$<$<CXX_COMPILER_ID:GNU>:-Werror>" "$<$<CXX_COMPILER_ID:GNU>:-pedantic-errors>" + "$<$<CXX_COMPILER_ID:GNU>:-fsanitize=address,leak,bounds,alignment,return,integer-divide-by-zero,vla-bound,null,enum,pointer-overflow>" ) #[============================================================================[ @@ -115,6 +116,13 @@ 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 #]============================================================================] @@ -128,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 c5624d8..e9f8d5f 100644 --- a/arch/x86_64/CMakeLists.txt +++ b/arch/x86_64/CMakeLists.txt @@ -59,6 +59,14 @@ 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" +) + +#[============================================================================[ +# The Shared Library +#]============================================================================] + +target_sources("_shared" PRIVATE "src/shared/mutex.cpp" ) 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..011f45c 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 <atomic> #include <cstdint> @@ -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. @@ -26,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 *; + 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; + 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/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 <concepts> - -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<typename T> - concept HeapAllocator = requires(T t, uint8_t * pointer, std::size_t size) { - { t.allocate(size) } -> std::same_as<uint8_t *>; - { t.deallocate(pointer, size) } -> std::same_as<void>; - }; - -} // 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 new file mode 100644 index 0000000..dff837e --- /dev/null +++ b/arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp @@ -0,0 +1,82 @@ +#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" + +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 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 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 + */ + static auto deallocate(void * pointer) noexcept -> void; + + private: + 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 + +auto operator new(std::size_t size) -> void *; + +auto operator delete(void * pointer) noexcept -> void; + +auto operator delete(void * pointer, std::size_t size) noexcept -> void; + +auto operator new[](std::size_t size) -> void *; + +auto operator delete[](void * pointer) noexcept -> void; + +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/include/arch/memory/heap/heap_allocator.hpp b/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp new file mode 100644 index 0000000..6aed3d8 --- /dev/null +++ b/arch/x86_64/include/arch/memory/heap/heap_allocator.hpp @@ -0,0 +1,43 @@ +#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 +{ + 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 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/include/arch/memory/heap/linked_list_allocator.hpp b/arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp index 06b21bb..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 @@ -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. @@ -21,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 @@ -31,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) noexcept -> void override; private: /** @@ -78,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. @@ -127,6 +117,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/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/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<typename T> + struct shared_pointer + { + explicit shared_pointer(T * pointer = nullptr) + : pointer(pointer) + , ref_count(new std::atomic<int>(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<int>(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<int> * ref_count; + }; + + template<typename T, typename... Args> + shared_pointer<T> make_shared(Args &&... args) + { + return shared_pointer<T>(new T(std::forward<Args>(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<typename T> + 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<typename T, typename... Args> + unique_pointer<T> make_unique(Args &&... args) + { + return unique_pointer<T>(new T(std::forward<Args>(args)...)); + } +} // namespace teachos::arch::stl + +#endif // TEACHOS_ARCH_X86_64_STL_UNIQUE_POINTER_HPP
\ No newline at end of file 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 <algorithm> + +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<typename T> + 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<T> 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<T> & operator=(vector<T> 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<shared::contiguous_pointer_iterator<T>> vector_container; + }; + +} // namespace teachos::arch::stl + +#endif // TEACHOS_ARCH_X86_64_STL_VECTOR_HPP diff --git a/arch/x86_64/src/boot/boot.s b/arch/x86_64/src/boot/boot.s index 8d27ea1..2197dce 100644 --- a/arch/x86_64/src/boot/boot.s +++ b/arch/x86_64/src/boot/boot.s @@ -197,8 +197,10 @@ _start: call enable_paging call enable_sse + cli // Clears the interrupt flag during the GDT setup lgdt (global_descriptor_table_pointer) jmp $global_descriptor_table_code,$_transition_to_long_mode + // The interrupt flag is set in cpp after setting up the GDT call halt diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index 681f960..472aed5 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -1,8 +1,7 @@ #include "arch/kernel/main.hpp" #include "arch/memory/heap/bump_allocator.hpp" -#include "arch/memory/heap/concept.hpp" -#include "arch/memory/heap/linked_list_allocator.hpp" +#include "arch/memory/heap/global_heap_allocator.hpp" #include "arch/memory/main.hpp" #include "arch/memory/multiboot/reader.hpp" #include "arch/video/vga/text.hpp" @@ -22,12 +21,8 @@ namespace teachos::arch::kernel auto heap_test() -> void { - memory::heap::linked_list_allocator heap_allocator{memory::heap::HEAP_START, - memory::heap::HEAP_START + memory::heap::HEAP_SIZE}; - auto test = heap_allocator.allocate(1024); - auto test2 = new (test) memory::multiboot::memory_information{}; - auto test3 = new (static_cast<void *>(static_cast<memory::multiboot::memory_information *>(test) + 1)) - memory::multiboot::memory_information{}; + auto test2 = new memory::multiboot::memory_information{}; + auto test3 = new memory::multiboot::memory_information{}; auto test4 = *test2; auto test5 = *test3; test4.kernel_end = 5000; @@ -42,18 +37,11 @@ namespace teachos::arch::kernel test2->kernel_end = 2000; test2->kernel_start = 1000; test2->multiboot_start = 2000; - heap_allocator.deallocate(test, 1024); + delete test2; + delete test3; - auto test9 = heap_allocator.allocate(1024); - auto test10 = heap_allocator.allocate(1024); - auto test11 = heap_allocator.allocate(1024); - heap_allocator.deallocate(test9, 1024); - auto test12 = heap_allocator.allocate(1024); - auto test13 = heap_allocator.allocate(1024); |
