forked from Bananymous/banan-os
Kernel: fork() now copies allocation done through GeneralAllocator
This commit is contained in:
parent
6fdbe6f9c2
commit
636c308993
|
@ -19,6 +19,8 @@ namespace Kernel
|
||||||
vaddr_t allocate(size_t);
|
vaddr_t allocate(size_t);
|
||||||
bool deallocate(vaddr_t);
|
bool deallocate(vaddr_t);
|
||||||
|
|
||||||
|
BAN::ErrorOr<GeneralAllocator*> clone(MMU&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Allocation
|
struct Allocation
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <kernel/Memory/GeneralAllocator.h>
|
#include <kernel/Memory/GeneralAllocator.h>
|
||||||
|
#include <kernel/Memory/MMUScope.h>
|
||||||
#include <kernel/Process.h>
|
#include <kernel/Process.h>
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
|
@ -61,4 +62,45 @@ namespace Kernel
|
||||||
return false;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -218,10 +218,10 @@ namespace Kernel
|
||||||
ASSERT(m_threads.front() == &Thread::current());
|
ASSERT(m_threads.front() == &Thread::current());
|
||||||
|
|
||||||
//for (auto& allocator : m_fixed_width_allocators)
|
//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)
|
if (m_general_allocator)
|
||||||
// forked->m_general_allocator = m_general_allocator->clone();
|
forked->m_general_allocator = MUST(m_general_allocator->clone(forked->mmu()));
|
||||||
|
|
||||||
Thread* thread = MUST(m_threads.front()->clone(forked, rsp, rip));
|
Thread* thread = MUST(m_threads.front()->clone(forked, rsp, rip));
|
||||||
forked->add_thread(thread);
|
forked->add_thread(thread);
|
||||||
|
|
|
@ -8,15 +8,18 @@
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
char* string = (char*)malloc(5000);
|
||||||
|
strcpy(string, "Hello");
|
||||||
|
|
||||||
printf("forking\n");
|
printf("forking\n");
|
||||||
|
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
{
|
{
|
||||||
printf("child\n");
|
printf("child '%s'\n", string);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
printf("parent\n");
|
printf("parent '%s'\n", string);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue