mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 07:27:45 +00:00
Kernel: Merge PurgeableVMObject into AnonymousVMObject
This implements memory commitments and lazy-allocation of committed memory.
This commit is contained in:
parent
b2a52f6208
commit
476f17b3f1
35 changed files with 937 additions and 564 deletions
|
@ -33,6 +33,7 @@
|
|||
#include <Kernel/Profiling.h>
|
||||
#include <Kernel/Random.h>
|
||||
#include <Kernel/Time/TimeManagement.h>
|
||||
#include <Kernel/VM/AllocationStrategy.h>
|
||||
#include <Kernel/VM/MemoryManager.h>
|
||||
#include <Kernel/VM/PageDirectory.h>
|
||||
#include <Kernel/VM/Region.h>
|
||||
|
@ -172,7 +173,7 @@ KResultOr<Process::LoadResult> Process::load_elf_object(FileDescription& object_
|
|||
return IterationDecision::Break;
|
||||
}
|
||||
|
||||
master_tls_region = allocate_region({}, program_header.size_in_memory(), String::formatted("{} (master-tls)", elf_name), PROT_READ | PROT_WRITE);
|
||||
master_tls_region = allocate_region({}, program_header.size_in_memory(), String::formatted("{} (master-tls)", elf_name), PROT_READ | PROT_WRITE, AllocationStrategy::Reserve);
|
||||
if (!master_tls_region) {
|
||||
ph_load_result = KResult(-ENOMEM);
|
||||
return IterationDecision::Break;
|
||||
|
@ -206,7 +207,7 @@ KResultOr<Process::LoadResult> Process::load_elf_object(FileDescription& object_
|
|||
if (program_header.is_writable())
|
||||
prot |= PROT_WRITE;
|
||||
auto region_name = String::formatted("{} (data-{}{})", elf_name, program_header.is_readable() ? "r" : "", program_header.is_writable() ? "w" : "");
|
||||
auto* region = allocate_region(program_header.vaddr().offset(load_offset), program_header.size_in_memory(), move(region_name), prot);
|
||||
auto* region = allocate_region(program_header.vaddr().offset(load_offset), program_header.size_in_memory(), move(region_name), prot, AllocationStrategy::Reserve);
|
||||
if (!region) {
|
||||
ph_load_result = KResult(-ENOMEM);
|
||||
return IterationDecision::Break;
|
||||
|
@ -259,7 +260,7 @@ KResultOr<Process::LoadResult> Process::load_elf_object(FileDescription& object_
|
|||
return KResult(-ENOEXEC);
|
||||
}
|
||||
|
||||
auto* stack_region = allocate_region(VirtualAddress(), Thread::default_userspace_stack_size, "Stack (Main thread)", PROT_READ | PROT_WRITE, false);
|
||||
auto* stack_region = allocate_region(VirtualAddress(), Thread::default_userspace_stack_size, "Stack (Main thread)", PROT_READ | PROT_WRITE, AllocationStrategy::Reserve);
|
||||
if (!stack_region)
|
||||
return KResult(-ENOMEM);
|
||||
stack_region->set_stack(true);
|
||||
|
|
|
@ -104,13 +104,17 @@ pid_t Process::sys$fork(RegisterState& regs)
|
|||
|
||||
ScopedSpinLock processes_lock(g_processes_lock);
|
||||
g_processes->prepend(child);
|
||||
child->ref(); // This reference will be dropped by Process::reap
|
||||
}
|
||||
|
||||
ScopedSpinLock lock(g_scheduler_lock);
|
||||
child_first_thread->set_affinity(Thread::current()->affinity());
|
||||
child_first_thread->set_state(Thread::State::Runnable);
|
||||
return child->pid().value();
|
||||
|
||||
auto child_pid = child->pid().value();
|
||||
// We need to leak one reference so we don't destroy the Process,
|
||||
// which will be dropped by Process::reap
|
||||
(void)child.leak_ref();
|
||||
return child_pid;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include <Kernel/Process.h>
|
||||
#include <Kernel/VM/PageDirectory.h>
|
||||
#include <Kernel/VM/PrivateInodeVMObject.h>
|
||||
#include <Kernel/VM/PurgeableVMObject.h>
|
||||
#include <Kernel/VM/Region.h>
|
||||
#include <Kernel/VM/SharedInodeVMObject.h>
|
||||
#include <LibC/limits.h>
|
||||
|
@ -142,9 +141,10 @@ void* Process::sys$mmap(Userspace<const Syscall::SC_mmap_params*> user_params)
|
|||
}
|
||||
|
||||
if (map_anonymous) {
|
||||
region = allocate_region(range.value(), !name.is_null() ? name : "mmap", prot, !map_noreserve);
|
||||
auto strategy = map_noreserve ? AllocationStrategy::None : AllocationStrategy::Reserve;
|
||||
region = allocate_region(range.value(), !name.is_null() ? name : "mmap", prot, strategy);
|
||||
if (!region && (!map_fixed && addr != 0))
|
||||
region = allocate_region(allocate_range({}, size), !name.is_null() ? name : "mmap", prot, !map_noreserve);
|
||||
region = allocate_region(allocate_range({}, size), !name.is_null() ? name : "mmap", prot, strategy);
|
||||
} else {
|
||||
if (offset < 0)
|
||||
return (void*)-EINVAL;
|
||||
|
@ -280,7 +280,7 @@ int Process::sys$madvise(void* address, size_t size, int advice)
|
|||
if (set_volatile && set_nonvolatile)
|
||||
return -EINVAL;
|
||||
if (set_volatile || set_nonvolatile) {
|
||||
if (!region->vmobject().is_purgeable())
|
||||
if (!region->vmobject().is_anonymous())
|
||||
return -EPERM;
|
||||
bool was_purged = false;
|
||||
switch (region->set_volatile(VirtualAddress(address), size, set_volatile, was_purged)) {
|
||||
|
@ -296,7 +296,7 @@ int Process::sys$madvise(void* address, size_t size, int advice)
|
|||
return 0;
|
||||
}
|
||||
if (advice & MADV_GET_VOLATILE) {
|
||||
if (!region->vmobject().is_purgeable())
|
||||
if (!region->vmobject().is_anonymous())
|
||||
return -EPERM;
|
||||
return region->is_volatile(VirtualAddress(address), size) ? 0 : 1;
|
||||
}
|
||||
|
|
|
@ -26,9 +26,9 @@
|
|||
|
||||
#include <AK/NonnullRefPtrVector.h>
|
||||
#include <Kernel/Process.h>
|
||||
#include <Kernel/VM/AnonymousVMObject.h>
|
||||
#include <Kernel/VM/InodeVMObject.h>
|
||||
#include <Kernel/VM/MemoryManager.h>
|
||||
#include <Kernel/VM/PurgeableVMObject.h>
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
|
@ -39,12 +39,11 @@ int Process::sys$purge(int mode)
|
|||
return -EPERM;
|
||||
int purged_page_count = 0;
|
||||
if (mode & PURGE_ALL_VOLATILE) {
|
||||
NonnullRefPtrVector<PurgeableVMObject> vmobjects;
|
||||
NonnullRefPtrVector<AnonymousVMObject> vmobjects;
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
MM.for_each_vmobject([&](auto& vmobject) {
|
||||
if (vmobject.is_purgeable())
|
||||
vmobjects.append(static_cast<PurgeableVMObject&>(vmobject));
|
||||
vmobjects.append(vmobject);
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ int Process::sys$shbuf_create(int size, void** buffer)
|
|||
return -EINVAL;
|
||||
size = PAGE_ROUND_UP(size);
|
||||
|
||||
auto vmobject = PurgeableVMObject::create_with_size(size);
|
||||
auto vmobject = AnonymousVMObject::create_with_size(size, AllocationStrategy::Reserve);
|
||||
if (!vmobject)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
@ -61,6 +61,10 @@ int Process::sys$create_thread(void* (*entry)(void*), Userspace<const Syscall::S
|
|||
// FIXME: Do something with guard pages?
|
||||
|
||||
auto thread = adopt(*new Thread(*this));
|
||||
if (!thread->was_created()) {
|
||||
// Could not fully create a thread
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
// We know this thread is not the main_thread,
|
||||
// So give it a unique name until the user calls $set_thread_name on it
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue