3#include "MappingIndex.h"
4#include "pedigree/kernel/utilities/assert.h"
6void* __libc_malloc(
size_t);
7void __libc_free(
void*);
9HostedMappingIndex::HostedMappingIndex()
10 : m_Entries(nullptr), m_Capacity(0), m_Live(0), m_Used(0) {}
12HostedMappingIndex::~HostedMappingIndex() {
14 __libc_free(m_Entries);
17size_t HostedMappingIndex::hash(uintptr_t page) {
19 uint64_t value = page;
20 value = (value ^ (value >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
21 value = (value ^ (value >> 27)) * UINT64_C(0x94d049bb133111eb);
22 return static_cast<size_t>(value ^ (value >> 31));
25size_t HostedMappingIndex::lookup(uintptr_t page)
const {
29 size_t index = hash(page) & (m_Capacity - 1);
30 for (
size_t probes = 0; probes < m_Capacity; ++probes) {
31 const Entry& entry = m_Entries[index];
32 if (entry.state == Empty)
34 if (entry.state == Occupied && entry.page == page)
36 index = (index + 1) & (m_Capacity - 1);
41bool HostedMappingIndex::reserveForInsert() {
42 if (m_Used < m_Capacity / 2)
45 size_t capacity = m_Capacity ? m_Capacity : 16;
48 if (m_Live >= capacity / 2) {
49 if (capacity > Missing / 2)
53 if (capacity > Missing /
sizeof(Entry))
57 auto* entries =
static_cast<Entry*
>(__libc_malloc(capacity *
sizeof(Entry)));
60 for (
size_t i = 0; i < capacity; ++i)
61 entries[i].state = Empty;
62 for (
size_t i = 0; i < m_Capacity; ++i) {
63 if (m_Entries[i].state != Occupied)
65 size_t index = hash(m_Entries[i].page) & (capacity - 1);
66 while (entries[index].state != Empty)
67 index = (index + 1) & (capacity - 1);
68 entries[index] = m_Entries[i];
71 Entry* previous = m_Entries;
73 m_Capacity = capacity;
76 __libc_free(previous);
80void HostedMappingIndex::insert(uintptr_t page,
size_t slot) {
82 assert(m_Capacity && m_Used < m_Capacity / 2);
83 if (!m_Capacity || slot == Missing)
86 size_t index = hash(page) & (m_Capacity - 1);
87 size_t deleted = Missing;
88 for (
size_t probes = 0; probes < m_Capacity; ++probes) {
89 Entry& entry = m_Entries[index];
90 if (entry.state == Occupied && entry.page == page) {
94 if (entry.state == Deleted && deleted == Missing)
96 if (entry.state == Empty) {
97 const size_t target = deleted == Missing ? index : deleted;
98 m_Entries[target] = {page, slot, Occupied};
100 if (deleted == Missing)
104 index = (index + 1) & (m_Capacity - 1);
109void HostedMappingIndex::erase(uintptr_t page) {
113 size_t index = hash(page) & (m_Capacity - 1);
114 for (
size_t probes = 0; probes < m_Capacity; ++probes) {
115 Entry& entry = m_Entries[index];
116 if (entry.state == Empty)
118 if (entry.state == Occupied && entry.page == page) {
119 entry.state = Deleted;
123 index = (index + 1) & (m_Capacity - 1);
127void HostedMappingIndex::clear() {
128 for (
size_t i = 0; i < m_Capacity; ++i)
129 m_Entries[i].state = Empty;