aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/include
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/include')
-rw-r--r--arch/x86_64/include/arch/kernel/interrupt.hpp26
-rw-r--r--arch/x86_64/include/arch/memory/heap/bump_allocator.hpp2
-rw-r--r--arch/x86_64/include/arch/memory/heap/global_heap_allocator.hpp2
-rw-r--r--arch/x86_64/include/arch/memory/heap/heap_allocator.hpp2
-rw-r--r--arch/x86_64/include/arch/memory/heap/linked_list_allocator.hpp2
-rw-r--r--arch/x86_64/include/arch/stl/shared_pointer.hpp120
-rw-r--r--arch/x86_64/include/arch/stl/unique_pointer.hpp68
-rw-r--r--arch/x86_64/include/arch/stl/vector.hpp193
8 files changed, 385 insertions, 30 deletions
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 <cstdint>
-
-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/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/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