1#include "pedigree/kernel/core/SlamBitmap.h"
2#include "pedigree/kernel/utilities/utility.h"
4void SlamBitmap::useMemory(
void* memory,
size_t entryCount,
size_t pageCount) {
5 m_reserved =
static_cast<uint64_t*
>(adjust_pointer(memory, 0));
6 m_mapped =
static_cast<uint64_t*
>(adjust_pointer(memory, entryCount *
sizeof(uint64_t)));
7 m_ready =
static_cast<uint64_t*
>(adjust_pointer(memory, entryCount *
sizeof(uint64_t) * 2));
9 m_EntryCount = entryCount;
10 m_PageCount = pageCount;
14uint64_t SlamBitmap::reservedBits(
size_t entry)
const {
15 return m_reserved[entry];
18uintptr_t SlamBitmap::metadataAddress(
size_t entry)
const {
21 return reinterpret_cast<uintptr_t
>(&m_reserved[entry]);
24static bool hasFreePage(uint64_t reserved,
size_t firstPage,
size_t pageCount) {
25 const size_t bits = pageCount - firstPage < 64 ? pageCount - firstPage : 64;
26 const uint64_t valid = bits == 64 ? ~uint64_t(0) : (uint64_t(1) << bits) - 1;
27 return (reserved & valid) != valid;
30size_t SlamBitmap::findFreeRun(
size_t pageCount)
const {
33 for (
size_t entryIndex = m_FirstFreeEntry; entryIndex < m_EntryCount; ++entryIndex) {
34 const size_t entryBase = entryIndex * 64;
35 const size_t bits = (m_PageCount - entryBase < 64) ? m_PageCount - entryBase : 64;
36 const uint64_t bitmap = m_reserved[entryIndex];
41 if (runLength >= pageCount)
45 if (bitmap == ~uint64_t(0)) {
49 for (
size_t bit = 0; bit < bits;) {
50 const uint64_t remaining = bitmap >> bit;
53 bit += (remaining == ~uint64_t(0)) ? bits - bit : __builtin_ctzll(~remaining);
55 const size_t freeBits = remaining ? __builtin_ctzll(remaining) : bits - bit;
56 const size_t span = freeBits < bits - bit ? freeBits : bits - bit;
58 runStart = entryBase + bit;
60 if (runLength >= pageCount)
66 return static_cast<size_t>(-1);
69void SlamBitmap::reserve(
size_t firstPage,
size_t pageCount) {
70 for (
size_t i = 0; i < pageCount; ++i)
72 m_reserved[(firstPage + i) / 64] |= uint64_t(1) << ((firstPage + i) % 64);
74 while (m_FirstFreeEntry < m_EntryCount &&
75 !hasFreePage(m_reserved[m_FirstFreeEntry], m_FirstFreeEntry * 64, m_PageCount))
79void SlamBitmap::release(
size_t firstPage,
size_t pageCount) {
80 for (
size_t i = 0; i < pageCount; ++i) {
81 const uint64_t bit = uint64_t(1) << ((firstPage + i) % 64);
82 size_t index = (firstPage + i) / 64;
83 m_mapped[index] &= ~bit;
84 m_ready[index] &= ~bit;
85 m_reserved[index] &= ~bit;
86 if (index < m_FirstFreeEntry)
87 m_FirstFreeEntry = index;
97void SlamBitmap::setMapped(
size_t page) {
99 m_mapped[page / 64] |= uint64_t(1) << (page % 64);
102void SlamBitmap::clearMappedAndReady(
size_t page) {
103 const uint64_t bit = uint64_t(1) << (page % 64);
104 size_t index = page / 64;
105 m_mapped[index] &= ~bit;
106 m_ready[index] &= ~bit;
114bool SlamBitmap::isReserved(
size_t page)
const {
116 return m_reserved[page / 64] & (uint64_t(1) << (page % 64));
119bool SlamBitmap::isMapped(
size_t page)
const {
121 return m_mapped[page / 64] & (uint64_t(1) << (page % 64));
124bool SlamBitmap::isReady(
size_t page)
const {
126 return m_ready[page / 64] & (uint64_t(1) << (page % 64));
129void SlamBitmap::setReady(
size_t page) {
131 m_ready[page / 64] |= uint64_t(1) << (page % 64);