diff --git a/kernel/src/memory/MemoryManager.cpp b/kernel/src/memory/MemoryManager.cpp index 6d335717..738df21b 100644 --- a/kernel/src/memory/MemoryManager.cpp +++ b/kernel/src/memory/MemoryManager.cpp @@ -4,6 +4,7 @@ #include "arch/MMU.h" #include "memory/KernelVM.h" #include "memory/MemoryMap.h" +#include "thread/Spinlock.h" #include #include #include @@ -16,13 +17,13 @@ extern const u8 end_of_kernel_rodata[1]; extern const u8 start_of_kernel_data[1]; extern const u8 end_of_kernel_data[1]; -static usize free_mem = 0; -static usize used_mem = 0; -static usize reserved_mem = 0; +static Atomic free_mem; +static Atomic used_mem; +static Atomic reserved_mem; -static u64 start_index = 0; +static Atomic start_index; -static Bitmap g_frame_bitmap; +static LockedValue g_frame_bitmap; #define CHECK_PAGE_ALIGNED(address) expect(is_aligned(address), "Address is not page-aligned") @@ -55,6 +56,8 @@ namespace MemoryManager MemoryMapIterator iter; MemoryMapEntry entry; + g_frame_bitmap.init(); + const auto largest_free_entry = iter.largest_free(); expect(largest_free_entry.is_free(), "We were given a largest free memory region that isn't even free!"); @@ -74,20 +77,24 @@ namespace MemoryManager expect(frame_bitmap_size < largest_free_entry.size(), "No single memory region is enough to hold the frame bitmap"); - g_frame_bitmap.initialize(frame_bitmap_addr, frame_bitmap_size); - - g_frame_bitmap.clear(true); // Set all pages to used/reserved by default, then clear out the free ones - - iter.rewind(); - while (iter.next().try_set_value(entry)) { - const u64 index = entry.address() / ARCH_PAGE_SIZE; - const usize pages = entry.size() / ARCH_PAGE_SIZE; - if (!entry.is_free()) { reserved_mem += entry.size(); } - else + auto frame_bitmap = g_frame_bitmap.lock(); + + frame_bitmap->initialize(frame_bitmap_addr, frame_bitmap_size); + + frame_bitmap->clear(true); // Set all pages to used/reserved by default, then clear out the free ones + + iter.rewind(); + while (iter.next().try_set_value(entry)) { - free_mem += entry.size(); - g_frame_bitmap.clear_region(index, pages, false); + const u64 index = entry.address() / ARCH_PAGE_SIZE; + const usize pages = entry.size() / ARCH_PAGE_SIZE; + if (!entry.is_free()) { reserved_mem += entry.size(); } + else + { + free_mem += entry.size(); + frame_bitmap->clear_region(index, pages, false); + } } } @@ -103,23 +110,27 @@ namespace MemoryManager // NOTE: We force these operations to succeed, because if we can't map the frame bitmap to virtual memory // there's no point in continuing. - auto bitmap_pages = g_frame_bitmap.size_in_bytes() / ARCH_PAGE_SIZE; + auto bitmap_pages = g_frame_bitmap.lock()->size_in_bytes() / ARCH_PAGE_SIZE; auto virtual_bitmap_base = KernelVM::alloc_several_pages(bitmap_pages) .expect_value("Unable to allocate virtual memory for the physical frame bitmap, cannot continue"); - map_frames_at(virtual_bitmap_base, (u64)g_frame_bitmap.location(), bitmap_pages, - MMU::ReadWrite | MMU::NoExecute) + + u64 phys = (u64)g_frame_bitmap.lock()->location(); + map_frames_at(virtual_bitmap_base, phys, bitmap_pages, MMU::ReadWrite | MMU::NoExecute) .expect_value("Unable to map the physical frame bitmap to virtual memory, cannot continue"); - g_frame_bitmap.initialize((void*)virtual_bitmap_base, g_frame_bitmap.size_in_bytes()); + auto frame_bitmap = g_frame_bitmap.lock(); + + frame_bitmap->initialize((void*)virtual_bitmap_base, frame_bitmap->size_in_bytes()); } void lock_frame(u64 frame) { const u64 index = frame / ARCH_PAGE_SIZE; - if (g_frame_bitmap.get(index)) return; - g_frame_bitmap.set(index, true); + auto frame_bitmap = g_frame_bitmap.lock(); + if (frame_bitmap->get(index)) return; + frame_bitmap->set(index, true); used_mem += ARCH_PAGE_SIZE; free_mem -= ARCH_PAGE_SIZE; } @@ -131,10 +142,11 @@ namespace MemoryManager Result alloc_frame() { - for (u64 index = start_index; index < g_frame_bitmap.size(); index++) + auto frame_bitmap = g_frame_bitmap.lock(); + for (u64 index = start_index; index < frame_bitmap->size(); index++) { - if (g_frame_bitmap.get(index)) continue; - g_frame_bitmap.set(index, true); + if (frame_bitmap->get(index)) continue; + frame_bitmap->set(index, true); start_index = index + 1; free_mem -= ARCH_PAGE_SIZE; used_mem += ARCH_PAGE_SIZE; @@ -147,9 +159,10 @@ namespace MemoryManager Result free_frame(u64 frame) { const u64 index = frame / ARCH_PAGE_SIZE; - if (index > g_frame_bitmap.size()) return err(EFAULT); - if (!g_frame_bitmap.get(index)) return err(EFAULT); - g_frame_bitmap.set(index, false); + auto frame_bitmap = g_frame_bitmap.lock(); + if (index > frame_bitmap->size()) return err(EFAULT); + if (!frame_bitmap->get(index)) return err(EFAULT); + frame_bitmap->set(index, false); used_mem -= ARCH_PAGE_SIZE; free_mem += ARCH_PAGE_SIZE; if (start_index > index) start_index = index;