|
6 | 6 | #include "memory/vmm.hpp" |
7 | 7 | #include "libs/math.hpp" |
8 | 8 | #include <string.h> |
| 9 | +#include <atomic> |
9 | 10 |
|
10 | 11 | namespace kernel::memory { |
11 | | -HeapMap::Node* HeapMap::root = nullptr; |
| 12 | +std::atomic<HeapMap::Node*> HeapMap::root = nullptr; |
12 | 13 | SpinLock HeapMap::lock; |
13 | 14 |
|
14 | 15 | Slab* MetadataAllocator::alloc() { |
@@ -56,69 +57,77 @@ void HeapMap::set(void* ptr, Slab* meta) { |
56 | 57 | LockGuard guard(lock); |
57 | 58 | uintptr_t addr = reinterpret_cast<uintptr_t>(ptr); |
58 | 59 |
|
59 | | - if (!root) { |
60 | | - root = reinterpret_cast<Node*>(VirtualManager::allocate(1)); |
61 | | - if (!root) { |
62 | | - PANIC("Out of Memory!"); |
63 | | - } |
64 | | - } |
| 60 | + Node* l4 = root.load(std::memory_order_relaxed); |
65 | 61 |
|
66 | | - Node* l4 = root; |
| 62 | + if (!l4) { |
| 63 | + l4 = reinterpret_cast<Node*>(VirtualManager::allocate(1)); |
| 64 | + memset(l4, 0, PAGE_SIZE_4K); |
| 65 | + |
| 66 | + root.store(l4, std::memory_order_release); |
| 67 | + } |
67 | 68 |
|
68 | 69 | // Level 4 -> Level 3 |
69 | 70 | uintptr_t i4 = (addr >> 39) & MASK; |
70 | | - if (!l4->entries[i4]) { |
71 | | - l4->entries[i4] = VirtualManager::allocate(1); |
72 | | - } |
| 71 | + Node* l3 = static_cast<Node*>(l4->entries[i4].load(std::memory_order_relaxed)); |
| 72 | + if (!l3) { |
| 73 | + l3 = reinterpret_cast<Node*>(VirtualManager::allocate(1)); |
| 74 | + memset(l3, 0, PAGE_SIZE_4K); |
73 | 75 |
|
74 | | - Node* l3 = reinterpret_cast<Node*>(l4->entries[i4]); |
| 76 | + l4->entries[i4].store(l3, std::memory_order_release); |
| 77 | + } |
75 | 78 |
|
76 | 79 | // Level 3 -> Level 2 |
77 | 80 | uintptr_t i3 = (addr >> 30) & MASK; |
78 | | - if (!l3->entries[i3]) { |
79 | | - l3->entries[i3] = VirtualManager::allocate(1); |
80 | | - } |
| 81 | + Node* l2 = static_cast<Node*>(l3->entries[i3].load(std::memory_order_relaxed)); |
| 82 | + if (!l2) { |
| 83 | + l2 = reinterpret_cast<Node*>(VirtualManager::allocate(1)); |
| 84 | + memset(l2, 0, PAGE_SIZE_4K); |
81 | 85 |
|
82 | | - Node* l2 = reinterpret_cast<Node*>(l3->entries[i3]); |
| 86 | + l3->entries[i3].store(l2, std::memory_order_release); |
| 87 | + } |
83 | 88 |
|
84 | 89 | // Level 2 -> Level 1 |
85 | 90 | uintptr_t i2 = (addr >> 21) & MASK; |
86 | | - if (!l2->entries[i2]) { |
87 | | - l2->entries[i2] = VirtualManager::allocate(1); |
| 91 | + Node* l1 = static_cast<Node*>(l2->entries[i2].load(std::memory_order_relaxed)); |
| 92 | + if (!l1) { |
| 93 | + l1 = reinterpret_cast<Node*>(VirtualManager::allocate(1)); |
| 94 | + memset(l1, 0, PAGE_SIZE_4K); |
| 95 | + |
| 96 | + l2->entries[i2].store(l1, std::memory_order_release); |
88 | 97 | } |
89 | 98 |
|
90 | | - Node* l1 = reinterpret_cast<Node*>(l2->entries[i2]); |
91 | | - uintptr_t i1 = (addr >> 12) & MASK; |
92 | | - l1->entries[i1] = reinterpret_cast<void*>(meta); |
| 99 | + uintptr_t i1 = (addr >> 12) & MASK; |
| 100 | + l1->entries[i1].store(meta, std::memory_order_release); |
93 | 101 | } |
94 | 102 |
|
95 | 103 | Slab* HeapMap::get(void* ptr) { |
96 | 104 | uintptr_t addr = reinterpret_cast<uintptr_t>(ptr); |
97 | 105 |
|
98 | | - if (!root) { |
| 106 | + Node* l4 = root.load(std::memory_order_acquire); |
| 107 | + if (!l4) { |
99 | 108 | return nullptr; |
100 | 109 | } |
101 | 110 |
|
102 | | - Node* l4 = root; |
103 | | - Node* l3 = reinterpret_cast<Node*>(l4->entries[(addr >> 39) & MASK]); |
104 | | - |
| 111 | + uintptr_t i4 = (addr >> 39) & MASK; |
| 112 | + Node* l3 = static_cast<Node*>(l4->entries[i4].load(std::memory_order_acquire)); |
105 | 113 | if (!l3) { |
106 | 114 | return nullptr; |
107 | 115 | } |
108 | 116 |
|
109 | | - Node* l2 = reinterpret_cast<Node*>(l3->entries[(addr >> 30) & MASK]); |
110 | | - |
| 117 | + uintptr_t i3 = (addr >> 30) & MASK; |
| 118 | + Node* l2 = static_cast<Node*>(l3->entries[i3].load(std::memory_order_acquire)); |
111 | 119 | if (!l2) { |
112 | 120 | return nullptr; |
113 | 121 | } |
114 | 122 |
|
115 | | - Node* l1 = reinterpret_cast<Node*>(l2->entries[(addr >> 21) & MASK]); |
116 | | - |
| 123 | + uintptr_t i2 = (addr >> 21) & MASK; |
| 124 | + Node* l1 = static_cast<Node*>(l2->entries[i2].load(std::memory_order_acquire)); |
117 | 125 | if (!l1) { |
118 | 126 | return nullptr; |
119 | 127 | } |
120 | 128 |
|
121 | | - return reinterpret_cast<Slab*>(l1->entries[(addr >> 12) & MASK]); |
| 129 | + uintptr_t i1 = (addr >> 12) & MASK; |
| 130 | + return static_cast<Slab*>(l1->entries[i1].load(std::memory_order_acquire)); |
122 | 131 | } |
123 | 132 |
|
124 | 133 | void HeapTLB::init() { |
|
0 commit comments