[Zion] Use a binary tree to store address space mappings.

This commit is contained in:
Drew Galbraith 2023-11-03 19:47:39 -07:00
parent 98f029ae23
commit a16dcc2aa9
2 changed files with 21 additions and 20 deletions

View File

@ -39,13 +39,13 @@ uint64_t AddressSpace::GetNextMemMapAddr(uint64_t size) {
void AddressSpace::MapInMemoryObject( void AddressSpace::MapInMemoryObject(
uint64_t vaddr, const glcr::RefPtr<MemoryObject>& mem_obj) { uint64_t vaddr, const glcr::RefPtr<MemoryObject>& mem_obj) {
memory_mappings_.PushBack({.vaddr = vaddr, .mem_obj = mem_obj}); memory_mappings_.Insert(vaddr, {.vaddr = vaddr, .mem_obj = mem_obj});
} }
uint64_t AddressSpace::MapInMemoryObject( uint64_t AddressSpace::MapInMemoryObject(
const glcr::RefPtr<MemoryObject>& mem_obj) { const glcr::RefPtr<MemoryObject>& mem_obj) {
uint64_t vaddr = GetNextMemMapAddr(mem_obj->size()); uint64_t vaddr = GetNextMemMapAddr(mem_obj->size());
memory_mappings_.PushBack({.vaddr = vaddr, .mem_obj = mem_obj}); memory_mappings_.Insert(vaddr, {.vaddr = vaddr, .mem_obj = mem_obj});
return vaddr; return vaddr;
} }
@ -62,12 +62,13 @@ bool AddressSpace::HandlePageFault(uint64_t vaddr) {
return true; return true;
} }
MemoryMapping* mapping = GetMemoryMappingForAddr(vaddr); auto mapping_or = GetMemoryMappingForAddr(vaddr);
if (mapping == nullptr) { if (!mapping_or) {
return false; return false;
} }
uint64_t offset = vaddr - mapping->vaddr; MemoryMapping& mapping = mapping_or.value();
uint64_t physical_addr = mapping->mem_obj->PhysicalPageAtOffset(offset); uint64_t offset = vaddr - mapping.vaddr;
uint64_t physical_addr = mapping.mem_obj->PhysicalPageAtOffset(offset);
if (physical_addr == 0) { if (physical_addr == 0) {
dbgln("WARN: Memory object returned invalid physical addr."); dbgln("WARN: Memory object returned invalid physical addr.");
return false; return false;
@ -79,16 +80,15 @@ bool AddressSpace::HandlePageFault(uint64_t vaddr) {
return true; return true;
} }
AddressSpace::MemoryMapping* AddressSpace::GetMemoryMappingForAddr( glcr::Optional<glcr::Ref<AddressSpace::MemoryMapping>>
uint64_t vaddr) { AddressSpace::GetMemoryMappingForAddr(uint64_t vaddr) {
auto iter = memory_mappings_.begin(); auto mapping_or = memory_mappings_.Predecessor(vaddr + 1);
while (iter != memory_mappings_.end()) { if (!mapping_or) {
if ((vaddr >= (*iter).vaddr) && return mapping_or;
(vaddr < ((*iter).vaddr + (*iter).mem_obj->size()))) {
return &(*iter);
}
++iter;
} }
MemoryMapping& mapping = mapping_or.value();
return 0; if (mapping.vaddr + mapping.mem_obj->size() <= vaddr) {
return {};
}
return mapping_or;
} }

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <glacier/container/linked_list.h> #include <glacier/container/binary_tree.h>
#include <glacier/memory/ref_ptr.h> #include <glacier/memory/ref_ptr.h>
#include <stdint.h> #include <stdint.h>
@ -92,7 +92,8 @@ class AddressSpace : public KernelObject {
uint64_t vaddr; uint64_t vaddr;
glcr::RefPtr<MemoryObject> mem_obj; glcr::RefPtr<MemoryObject> mem_obj;
}; };
glcr::LinkedList<MemoryMapping> memory_mappings_; glcr::BinaryTree<uint64_t, MemoryMapping> memory_mappings_;
MemoryMapping* GetMemoryMappingForAddr(uint64_t vaddr); glcr::Optional<glcr::Ref<MemoryMapping>> GetMemoryMappingForAddr(
uint64_t vaddr);
}; };