Kernel: Make AddressSpaces reference-counted

This commit is contained in:
apio 2022-10-15 17:40:33 +02:00
parent eca7227fda
commit 68403dc029
3 changed files with 22 additions and 7 deletions

View File

@ -18,10 +18,11 @@ struct AddressSpace
bool is_cloned()
{
return m_cloned;
return *m_refs > 1;
}
private:
PageTable* m_pml4;
bool m_cloned;
int* m_refs;
};

View File

@ -4,22 +4,25 @@
#include "log/Log.h"
#include "memory/PMM.h"
#include "memory/VMM.h"
#include "std/stdlib.h"
#include "utils/move.h"
AddressSpace AddressSpace::create()
{
AddressSpace result;
result.m_pml4 = (PageTable*)PMM::request_page();
result.m_cloned = false;
result.m_refs = (int*)kmalloc(sizeof(int));
*result.m_refs = 1;
VMM::install_kernel_page_directory_into_address_space(result);
return move(result);
}
void AddressSpace::destroy()
{
if (m_cloned)
if (is_cloned())
{
kdbgln("Will not destroy a cloned address space, I don't own it");
(*m_refs)--;
return;
}
uint64_t pages_freed = 0;
@ -75,21 +78,26 @@ void AddressSpace::destroy()
pages_freed++;
PMM::free_page(m_pml4);
kfree(m_refs);
kdbgln("Reclaimed %ld pages from address space!", pages_freed);
}
void AddressSpace::detach()
{
if (!m_cloned) return;
if (!is_cloned()) return;
(*m_refs)--;
m_refs = (int*)kmalloc(sizeof(int));
*m_refs = 1;
m_pml4 = (PageTable*)PMM::request_page();
VMM::install_kernel_page_directory_into_address_space(*this);
m_cloned = false;
}
AddressSpace AddressSpace::clone()
{
AddressSpace result;
result.m_pml4 = m_pml4;
result.m_cloned = true;
result.m_refs = m_refs;
*m_refs = *m_refs + 1;
return result;
}

View File

@ -73,6 +73,12 @@ void sys_exec(Context* context, const char* pathname)
Task* task = Scheduler::current_task();
ASSERT(task);
if (task->address_space.is_cloned())
{
task->address_space.detach();
VMM::switch_to_user_address_space(task->address_space);
}
// At this point, pretty much nothing can fail.
ELFImage* image = ELFLoader::load_elf_from_vfs(program);