Kernel: fork() now copies allocation done through GeneralAllocator

This commit is contained in:
Bananymous 2023-05-28 20:37:39 +03:00
parent 6fdbe6f9c2
commit 636c308993
4 changed files with 52 additions and 5 deletions

View File

@ -19,6 +19,8 @@ namespace Kernel
vaddr_t allocate(size_t);
bool deallocate(vaddr_t);
BAN::ErrorOr<GeneralAllocator*> clone(MMU&);
private:
struct Allocation
{

View File

@ -1,4 +1,5 @@
#include <kernel/Memory/GeneralAllocator.h>
#include <kernel/Memory/MMUScope.h>
#include <kernel/Process.h>
namespace Kernel
@ -61,4 +62,45 @@ namespace Kernel
return false;
}
BAN::ErrorOr<GeneralAllocator*> GeneralAllocator::clone(MMU& new_mmu)
{
GeneralAllocator* allocator = new GeneralAllocator(new_mmu);
if (allocator == nullptr)
return BAN::Error::from_errno(ENOMEM);
MMUScope _(m_mmu);
ASSERT(m_mmu.is_page_free(0));
for (auto& allocation : m_allocations)
{
Allocation new_allocation;
ASSERT(new_mmu.is_range_free(allocation.address, allocation.pages.size() * PAGE_SIZE));
new_allocation.address = allocation.address;
MUST(new_allocation.pages.reserve(allocation.pages.size()));
uint8_t flags = m_mmu.get_page_flags(allocation.address);
for (size_t i = 0; i < allocation.pages.size(); i++)
{
paddr_t paddr = Heap::get().take_free_page();
ASSERT(paddr);
vaddr_t vaddr = allocation.address + i * PAGE_SIZE;
MUST(new_allocation.pages.push_back(paddr));
new_mmu.map_page_at(paddr, vaddr, flags);
m_mmu.map_page_at(paddr, 0, MMU::Flags::ReadWrite | MMU::Flags::Present);
m_mmu.invalidate(0);
memcpy((void*)0, (void*)vaddr, PAGE_SIZE);
}
MUST(allocator->m_allocations.push_back(BAN::move(new_allocation)));
}
m_mmu.unmap_page(0);
m_mmu.invalidate(0);
return allocator;
}
}

View File

@ -218,10 +218,10 @@ namespace Kernel
ASSERT(m_threads.front() == &Thread::current());
//for (auto& allocator : m_fixed_width_allocators)
// MUST(forked->m_fixed_width_allocators.push_back(allocator.clone()));
// MUST(forked->m_fixed_width_allocators.push_back(MUST(allocator->clone(forked->mmu()))));
//if (m_general_allocator)
// forked->m_general_allocator = m_general_allocator->clone();
if (m_general_allocator)
forked->m_general_allocator = MUST(m_general_allocator->clone(forked->mmu()));
Thread* thread = MUST(m_threads.front()->clone(forked, rsp, rip));
forked->add_thread(thread);

View File

@ -8,15 +8,18 @@
int main()
{
char* string = (char*)malloc(5000);
strcpy(string, "Hello");
printf("forking\n");
pid_t pid = fork();
if (pid == 0)
{
printf("child\n");
printf("child '%s'\n", string);
return 0;
}
printf("parent\n");
printf("parent '%s'\n", string);
return 0;
}