diff options
Diffstat (limited to 'kernel/src')
| -rw-r--r-- | kernel/src/memory/bitmap_allocator.cpp | 100 |
1 files changed, 100 insertions, 0 deletions
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 <algorithm> +#include <cstddef> +#include <cstdint> +#include <optional> +#include <span> +#include <utility> + +namespace kernel::memory +{ + + bitmap_frame_allocator::bitmap_frame_allocator(std::span<std::uint64_t> 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<std::pair<kapi::memory::frame, std::size_t>> + { + 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<kapi::memory::frame, std::size_t> 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 |
