From e284d574ed9237a215d994861cc502452fec11ce Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 13 Mar 2026 22:28:50 +0100 Subject: kernel/memory: implement basic bitmap allocator --- kernel/src/memory/bitmap_allocator.cpp | 100 +++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 kernel/src/memory/bitmap_allocator.cpp (limited to 'kernel/src/memory') diff --git a/kernel/src/memory/bitmap_allocator.cpp b/kernel/src/memory/bitmap_allocator.cpp new file mode 100644 index 0000000..c010f77 --- /dev/null +++ b/kernel/src/memory/bitmap_allocator.cpp @@ -0,0 +1,100 @@ +#include "kernel/memory/bitmap_allocator.hpp" + +#include "kapi/memory.hpp" + +#include +#include +#include +#include +#include +#include + +namespace kernel::memory +{ + + bitmap_frame_allocator::bitmap_frame_allocator(std::span storage, std::size_t frame_count) noexcept + : m_bitmap{storage} + , m_frame_count{frame_count} + , m_last_index{} + { + std::ranges::fill(m_bitmap, ~0uz); + } + + auto bitmap_frame_allocator::allocate_many(std::size_t count) noexcept + -> std::optional> + { + if (count == 0) + { + return std::nullopt; + } + + auto free_count = 0uz; + auto first_free = 0uz; + + for (auto i = 0uz; i < m_frame_count; ++i) + { + auto const current = (m_last_index + i) % m_frame_count; + if (!test(current)) + { + if (free_count == 0) + { + first_free = current; + } + + ++free_count; + + if (free_count == count) + { + for (auto j = 0uz; j < count; ++j) + { + set(first_free + j); + } + m_last_index = first_free + count; + return std::make_pair(kapi::memory::frame{first_free}, count); + } + } + else + { + free_count = 0; + } + } + + return std::nullopt; + } + + auto bitmap_frame_allocator::release_many(std::pair frame_set) -> void + { + auto const [start, count] = frame_set; + for (auto i = 0uz; i < count; ++i) + { + clear(start.number() + i); + } + } + + auto bitmap_frame_allocator::mark_used(kapi::memory::frame frame) -> void + { + set(frame.number()); + } + + auto bitmap_frame_allocator::test(std::size_t index) const noexcept -> bool + { + auto entry_entry = index / 64; + auto entry_offset = index % 64; + return (m_bitmap[entry_entry] & (1uz << entry_offset)); + } + + auto bitmap_frame_allocator::set(std::size_t index) noexcept -> void + { + auto entry_entry = index / 64; + auto entry_offset = index % 64; + m_bitmap[entry_entry] |= (1uz << entry_offset); + } + + auto bitmap_frame_allocator::clear(std::size_t index) noexcept -> void + { + auto entry_entry = index / 64; + auto entry_offset = index % 64; + m_bitmap[entry_entry] &= ~(1uz << entry_offset); + } + +} // namespace kernel::memory \ No newline at end of file -- cgit v1.2.3