#include "kernel/memory/bitmap_allocator.hpp" #include "kapi/memory.hpp" #include #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{} { constexpr auto bits_per_word = 64uz; auto to_fill = (frame_count + bits_per_word - 1) / bits_per_word; std::ranges::fill(std::views::take(m_bitmap, to_fill), ~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 { constexpr auto bits_per_word = 64uz; auto entry_entry = index / bits_per_word; auto entry_offset = index % bits_per_word; return (m_bitmap[entry_entry] & (1uz << entry_offset)); } auto bitmap_frame_allocator::set(std::size_t index) noexcept -> void { constexpr auto bits_per_word = 64uz; auto entry_entry = index / bits_per_word; auto entry_offset = index % bits_per_word; m_bitmap[entry_entry] |= (1uz << entry_offset); } auto bitmap_frame_allocator::clear(std::size_t index) noexcept -> void { constexpr auto bits_per_word = 64uz; auto entry_entry = index / bits_per_word; auto entry_offset = index % bits_per_word; m_bitmap[entry_entry] &= ~(1uz << entry_offset); } } // namespace kernel::memory