The Pedigree Project 0.1
MemoryMappedFile-swap.cc
1/* Copyright (c) 2026, Pedigree Developers. */
2#include "pedigree/kernel/processor/PhysicalMemoryManager.h"
3#include "pedigree/kernel/processor/Processor.h"
4#include "pedigree/kernel/processor/ProcessorInformation.h"
5
6#include "MemoryMappedFile.h"
7
8SwapStatus MemoryMapManager::activateSwap(uint32_t endpoint) {
9 OperationGuard operation(*this);
10 return SwapStore::instance().activate(endpoint);
11}
12SwapStatus MemoryMapManager::deactivateSwap(uint32_t endpoint) {
13 OperationGuard operation(*this);
14 auto& store = SwapStore::instance();
15 if (!endpoint || store.endpointId() != endpoint)
16 return SwapStatus::NotActive;
17 auto& original = Processor::information().getVirtualAddressSpace();
18 SwapStatus status = SwapStatus::Success;
19 for (auto spaces = m_MmObjectLists.begin(); spaces != m_MmObjectLists.end(); ++spaces) {
20 Processor::switchAddressSpace(*spaces.key());
21 for (auto* object : *spaces.value()) {
22 status = object->restoreSwapPages(*spaces.key());
23 if (status != SwapStatus::Success)
24 break;
25 }
26 if (status != SwapStatus::Success)
27 break;
28 }
30 return status == SwapStatus::Success ? store.finishDeactivate(endpoint) : status;
31}
32SwapSnapshot MemoryMapManager::swapSnapshot() {
33 OperationGuard operation(*this);
34 return SwapStore::instance().snapshot();
35}
36
37SwapStatus MemoryMapManager::pageOutRange(uintptr_t base, size_t length) {
38 OperationGuard operation(*this);
39 const size_t pageSize = PhysicalMemoryManager::getPageSize();
40 if ((base & (pageSize - 1)) || (length & (pageSize - 1)) || length > ~uintptr_t(0) - base)
41 return SwapStatus::Invalid;
42 if (!SwapStore::instance().snapshot().active)
43 return SwapStatus::NotActive;
44 auto& space = Processor::information().getVirtualAddressSpace();
45 auto* objects = m_MmObjectLists.lookup(&space);
46 // Validate every owner before revocation; mixed or pinned ranges cannot
47 // silently turn an unsupported part of the range into success.
48 for (size_t pass = 0; pass < 2; ++pass) {
49 for (uintptr_t address = base; address < base + length; address += pageSize) {
50 MemoryMappedObject* owner = nullptr;
51 if (objects)
52 for (auto* object : *objects)
53 if (object->matches(address)) {
54 owner = object;
55 break;
56 }
57 if (!owner)
58 return SwapStatus::Unmapped;
59 if (!owner->supportsPageOut(space, address))
60 return SwapStatus::Unsupported;
61 if (pass) {
62 bool released = false;
63 const auto status = owner->pageOutAt(space, address, released);
64 if (status != SwapStatus::Success)
65 return status;
66 }
67 }
68 }
69 return SwapStatus::Success;
70}
Memory-mapped file interface.
Tree< VirtualAddressSpace *, MmObjectList * > m_MmObjectLists
static ProcessorInformation & information()
static void switchAddressSpace(VirtualAddressSpace &AddressSpace)