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/x86_64/memory/buffered_allocator.hpp67
1 files changed, 67 insertions, 0 deletions
diff --git a/arch/x86_64/include/x86_64/memory/buffered_allocator.hpp b/arch/x86_64/include/x86_64/memory/buffered_allocator.hpp
new file mode 100644
index 0000000..2d05010
--- /dev/null
+++ b/arch/x86_64/include/x86_64/memory/buffered_allocator.hpp
@@ -0,0 +1,67 @@
+#ifndef TEACHOS_X86_64_BUFFERED_ALLOCATOR_HPP
+#define TEACHOS_X86_64_BUFFERED_ALLOCATOR_HPP
+
+#include "kapi/memory.hpp"
+
+#include <algorithm>
+#include <array>
+#include <cstddef>
+
+namespace teachos::memory::x86_64
+{
+
+ template<std::size_t BufferSize>
+ struct buffered_allocator : frame_allocator
+ {
+ explicit buffered_allocator(frame_allocator * underlying)
+ : m_underlying{underlying}
+ {
+ std::ranges::generate(m_pool, [this] { return m_underlying->allocate(); });
+ }
+
+ buffered_allocator(buffered_allocator const &) = delete;
+ buffered_allocator(buffered_allocator &&) = default;
+
+ ~buffered_allocator() override
+ {
+ std::ranges::for_each(m_pool, [this](auto const & maybe_frame) {
+ if (maybe_frame)
+ {
+ m_underlying->release(*maybe_frame);
+ }
+ });
+ }
+
+ auto operator=(buffered_allocator const &) = delete;
+ auto operator=(buffered_allocator &&) = delete;
+
+ auto allocate() -> std::optional<frame> override
+ {
+ auto found = std::ranges::find_if(m_pool, [](auto const & candidate) { return candidate.has_value(); });
+ if (found == std::end(m_pool))
+ {
+ return m_underlying->allocate();
+ }
+ auto frame = found->value();
+ found->reset();
+ return frame;
+ }
+
+ auto release(frame frame) -> void override
+ {
+ auto found = std::ranges::find_if(m_pool, [](auto const & candidate) { return !candidate; });
+ if (found == std::end(m_pool))
+ {
+ return m_underlying->release(frame);
+ }
+ (*found) = frame;
+ }
+
+ private:
+ frame_allocator * m_underlying;
+ std::array<std::optional<frame>, BufferSize> m_pool{};
+ };
+
+} // namespace teachos::memory::x86_64
+
+#endif \ No newline at end of file