Use shared_ptr for PageTable

This commit is contained in:
Hamish Milne 2020-01-05 16:35:01 +00:00 committed by zhupengfei
parent e4afa8e512
commit 96432589bd
10 changed files with 34 additions and 33 deletions

2
TODO
View file

@ -3,7 +3,7 @@
☐ Multiple slots etc.
✔ CPU @done(19-08-13 15:41)
✔ Memory @done(19-08-13 15:41)
☐ Page tables
✔ Page tables @done(20-01-05 16:33)
Need to change uses to shared_ptr
✔ Skip N3DS RAM if unused @done(20-01-03 23:26)
✔ DSP @done(19-12-28 16:57)

View file

@ -61,7 +61,7 @@ private:
std::unique_ptr<Dynarmic::A32::Jit> MakeJit();
Dynarmic::A32::Jit* jit = nullptr;
Memory::PageTable* current_page_table = nullptr;
std::map<Memory::PageTable*, std::unique_ptr<Dynarmic::A32::Jit>> jits;
std::shared_ptr<Memory::PageTable> current_page_table = nullptr;
std::map<std::shared_ptr<Memory::PageTable>, std::unique_ptr<Dynarmic::A32::Jit>> jits;
std::shared_ptr<ARMul_State> interpreter_state;
};

View file

@ -52,10 +52,10 @@ std::shared_ptr<Process> KernelSystem::GetCurrentProcess() const {
void KernelSystem::SetCurrentProcess(std::shared_ptr<Process> process) {
current_process = process;
SetCurrentMemoryPageTable(&process->vm_manager.page_table);
SetCurrentMemoryPageTable(process->vm_manager.page_table);
}
void KernelSystem::SetCurrentMemoryPageTable(Memory::PageTable* page_table) {
void KernelSystem::SetCurrentMemoryPageTable(std::shared_ptr<Memory::PageTable> page_table) {
memory.SetCurrentPageTable(page_table);
if (current_cpu != nullptr) {
current_cpu->PageTableChanged(); // notify the CPU the page table in memory has changed

View file

@ -214,7 +214,7 @@ public:
std::shared_ptr<Process> GetCurrentProcess() const;
void SetCurrentProcess(std::shared_ptr<Process> process);
void SetCurrentMemoryPageTable(Memory::PageTable* page_table);
void SetCurrentMemoryPageTable(std::shared_ptr<Memory::PageTable> page_table);
void SetCPU(std::shared_ptr<ARM_Interface> cpu);

View file

@ -435,7 +435,7 @@ ResultCode Process::Unmap(VAddr target, VAddr source, u32 size, VMAPermission pe
Kernel::Process::Process(KernelSystem& kernel)
: Object(kernel), handle_table(kernel), vm_manager(kernel.memory), kernel(kernel) {
kernel.memory.RegisterPageTable(&vm_manager.page_table);
kernel.memory.RegisterPageTable(vm_manager.page_table);
}
Kernel::Process::~Process() {
// Release all objects this process owns first so that their potential destructor can do clean
@ -444,7 +444,7 @@ Kernel::Process::~Process() {
// memory etc.) even if they are still referenced by other processes.
handle_table.Clear();
kernel.memory.UnregisterPageTable(&vm_manager.page_table);
kernel.memory.UnregisterPageTable(vm_manager.page_table);
}
std::shared_ptr<Process> KernelSystem::GetProcessById(u32 process_id) const {

View file

@ -37,7 +37,8 @@ bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const {
return true;
}
VMManager::VMManager(Memory::MemorySystem& memory) : memory(memory) {
VMManager::VMManager(Memory::MemorySystem& memory)
: memory(memory), page_table(std::make_shared<Memory::PageTable>()) {
Reset();
}
@ -51,7 +52,7 @@ void VMManager::Reset() {
initial_vma.size = MAX_ADDRESS;
vma_map.emplace(initial_vma.base, initial_vma);
page_table.Clear();
page_table->Clear();
UpdatePageTableForVMA(initial_vma);
}
@ -348,13 +349,13 @@ VMManager::VMAIter VMManager::MergeAdjacent(VMAIter iter) {
void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
switch (vma.type) {
case VMAType::Free:
memory.UnmapRegion(page_table, vma.base, vma.size);
memory.UnmapRegion(*page_table, vma.base, vma.size);
break;
case VMAType::BackingMemory:
memory.MapMemoryRegion(page_table, vma.base, vma.size, vma.backing_memory);
memory.MapMemoryRegion(*page_table, vma.base, vma.size, vma.backing_memory);
break;
case VMAType::MMIO:
memory.MapIoRegion(page_table, vma.base, vma.size, vma.mmio_handler);
memory.MapIoRegion(*page_table, vma.base, vma.size, vma.mmio_handler);
break;
}
}

View file

@ -209,7 +209,7 @@ public:
/// Each VMManager has its own page table, which is set as the main one when the owning process
/// is scheduled.
Memory::PageTable page_table;
std::shared_ptr<Memory::PageTable> page_table;
private:
using VMAIter = decltype(vma_map)::iterator;

View file

@ -87,9 +87,9 @@ public:
std::unique_ptr<u8[]> vram = std::make_unique<u8[]>(Memory::VRAM_SIZE);
std::unique_ptr<u8[]> n3ds_extra_ram = std::make_unique<u8[]>(Memory::N3DS_EXTRA_RAM_SIZE);
PageTable* current_page_table = nullptr;
std::shared_ptr<PageTable> current_page_table = nullptr;
RasterizerCacheMarker cache_marker;
std::vector<PageTable*> page_table_list;
std::vector<std::shared_ptr<PageTable>> page_table_list;
AudioCore::DspInterface* dsp = nullptr;
@ -144,7 +144,7 @@ private:
ar& cache_marker;
ar& page_table_list;
// dsp is set from Core::System at startup
// TODO: current_page_table
ar& current_page_table;
ar& fcram_mem;
ar& vram_mem;
ar& n3ds_extra_ram_mem;
@ -190,11 +190,11 @@ void MemorySystem::serialize(Archive& ar, const unsigned int file_version) {
SERIALIZE_IMPL(MemorySystem)
void MemorySystem::SetCurrentPageTable(PageTable* page_table) {
void MemorySystem::SetCurrentPageTable(std::shared_ptr<PageTable> page_table) {
impl->current_page_table = page_table;
}
PageTable* MemorySystem::GetCurrentPageTable() const {
std::shared_ptr<PageTable> MemorySystem::GetCurrentPageTable() const {
return impl->current_page_table;
}
@ -259,11 +259,11 @@ MemoryRef MemorySystem::GetPointerForRasterizerCache(VAddr addr) {
UNREACHABLE();
}
void MemorySystem::RegisterPageTable(PageTable* page_table) {
void MemorySystem::RegisterPageTable(std::shared_ptr<PageTable> page_table) {
impl->page_table_list.push_back(page_table);
}
void MemorySystem::UnregisterPageTable(PageTable* page_table) {
void MemorySystem::UnregisterPageTable(std::shared_ptr<PageTable> page_table) {
impl->page_table_list.erase(
std::find(impl->page_table_list.begin(), impl->page_table_list.end(), page_table));
}
@ -351,7 +351,7 @@ void MemorySystem::Write(const VAddr vaddr, const T data) {
}
bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) {
auto& page_table = process.vm_manager.page_table;
auto& page_table = *process.vm_manager.page_table;
auto page_pointer = page_table.pointers[vaddr >> PAGE_BITS];
if (page_pointer)
@ -486,7 +486,7 @@ void MemorySystem::RasterizerMarkRegionCached(PAddr start, u32 size, bool cached
for (unsigned i = 0; i < num_pages; ++i, paddr += PAGE_SIZE) {
for (VAddr vaddr : PhysicalToVirtualAddressForRasterizer(paddr)) {
impl->cache_marker.Mark(vaddr, cached);
for (PageTable* page_table : impl->page_table_list) {
for (auto page_table : impl->page_table_list) {
PageType& page_type = page_table->attributes[vaddr >> PAGE_BITS];
if (cached) {
@ -608,7 +608,7 @@ u64 MemorySystem::Read64(const VAddr addr) {
void MemorySystem::ReadBlock(const Kernel::Process& process, const VAddr src_addr,
void* dest_buffer, const std::size_t size) {
auto& page_table = process.vm_manager.page_table;
auto& page_table = *process.vm_manager.page_table;
std::size_t remaining_size = size;
std::size_t page_index = src_addr >> PAGE_BITS;
@ -674,7 +674,7 @@ void MemorySystem::Write64(const VAddr addr, const u64 data) {
void MemorySystem::WriteBlock(const Kernel::Process& process, const VAddr dest_addr,
const void* src_buffer, const std::size_t size) {
auto& page_table = process.vm_manager.page_table;
auto& page_table = *process.vm_manager.page_table;
std::size_t remaining_size = size;
std::size_t page_index = dest_addr >> PAGE_BITS;
std::size_t page_offset = dest_addr & PAGE_MASK;
@ -722,7 +722,7 @@ void MemorySystem::WriteBlock(const Kernel::Process& process, const VAddr dest_a
void MemorySystem::ZeroBlock(const Kernel::Process& process, const VAddr dest_addr,
const std::size_t size) {
auto& page_table = process.vm_manager.page_table;
auto& page_table = *process.vm_manager.page_table;
std::size_t remaining_size = size;
std::size_t page_index = dest_addr >> PAGE_BITS;
std::size_t page_offset = dest_addr & PAGE_MASK;
@ -777,7 +777,7 @@ void MemorySystem::CopyBlock(const Kernel::Process& process, VAddr dest_addr, VA
void MemorySystem::CopyBlock(const Kernel::Process& dest_process,
const Kernel::Process& src_process, VAddr dest_addr, VAddr src_addr,
std::size_t size) {
auto& page_table = src_process.vm_manager.page_table;
auto& page_table = *src_process.vm_manager.page_table;
std::size_t remaining_size = size;
std::size_t page_index = src_addr >> PAGE_BITS;
std::size_t page_offset = src_addr & PAGE_MASK;

View file

@ -316,8 +316,8 @@ public:
void UnmapRegion(PageTable& page_table, VAddr base, u32 size);
/// Currently active page table
void SetCurrentPageTable(PageTable* page_table);
PageTable* GetCurrentPageTable() const;
void SetCurrentPageTable(std::shared_ptr<PageTable> page_table);
std::shared_ptr<PageTable> GetCurrentPageTable() const;
u8 Read8(VAddr addr);
u16 Read16(VAddr addr);
@ -367,10 +367,10 @@ public:
void RasterizerMarkRegionCached(PAddr start, u32 size, bool cached);
/// Registers page table for rasterizer cache marking
void RegisterPageTable(PageTable* page_table);
void RegisterPageTable(std::shared_ptr<PageTable> page_table);
/// Unregisters page table for rasterizer cache marking
void UnregisterPageTable(PageTable* page_table);
void UnregisterPageTable(std::shared_ptr<PageTable> page_table);
void SetDSP(AudioCore::DspInterface& dsp);

View file

@ -10,7 +10,7 @@
namespace ArmTests {
static Memory::PageTable* page_table = nullptr;
static std::shared_ptr<Memory::PageTable> page_table = nullptr;
TestEnvironment::TestEnvironment(bool mutable_memory_)
: mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) {
@ -20,7 +20,7 @@ TestEnvironment::TestEnvironment(bool mutable_memory_)
kernel = std::make_unique<Kernel::KernelSystem>(*memory, *timing, [] {}, 0);
kernel->SetCurrentProcess(kernel->CreateProcess(kernel->CreateCodeSet("", 0)));
page_table = &kernel->GetCurrentProcess()->vm_manager.page_table;
page_table = kernel->GetCurrentProcess()->vm_manager.page_table;
page_table->Clear();