diff options
| -rw-r--r-- | CMakeLists.txt | 8 | ||||
| -rw-r--r-- | arch/x86_64/CMakeLists.txt | 7 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/stl/vector.hpp | 193 |
3 files changed, 208 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d30a2c..8657cab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,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 #]============================================================================] @@ -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 <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 |
