1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-28 06:15:07 +00:00

Implement COW pages! :^)

sys$fork() now clones all writable regions with per-page COW bits.
The pages are then mapped read-only and we handle a PF by COWing the pages.

This is quite delightful. Obviously there's lots of work to do still,
and it needs better data structures, but the general concept works.
This commit is contained in:
Andreas Kling 2018-11-05 13:48:07 +01:00
parent e85c22fe58
commit 2d045d2a64
11 changed files with 271 additions and 97 deletions

View file

@ -19,6 +19,14 @@
//#define TASK_DEBUG
//#define FORK_DEBUG
//#define SCHEDULER_DEBUG
#define COOL_GLOBALS
#ifdef COOL_GLOBALS
struct CoolGlobals {
dword current_pid;
};
CoolGlobals* g_cool_globals;
#endif
// FIXME: Only do a single validation for accesses that don't span multiple pages.
// FIXME: Some places pass strlen(arg1) as arg2. This doesn't seem entirely perfect..
@ -96,6 +104,9 @@ static void hlt_loop()
void Process::initialize()
{
#ifdef COOL_GLOBALS
g_cool_globals = (CoolGlobals*)0x1000;
#endif
current = nullptr;
next_pid = 0;
s_processes = new InlineLinkedList<Process>;
@ -353,6 +364,7 @@ int Process::exec(const String& path, Vector<String>&& arguments, Vector<String>
m_tss.ds = 0x23;
m_tss.es = 0x23;
m_tss.fs = 0x23;
m_tss.gs = 0x23;
m_tss.ss = 0x23;
m_tss.cr3 = (dword)m_page_directory;
auto* stack_region = allocate_region(LinearAddress(), defaultStackSize, "stack");
@ -845,7 +857,7 @@ bool scheduleNewProcess()
for (auto* process = s_processes->head(); process; process = process->next()) {
//if (process->state() == Process::BlockedWait || process->state() == Process::BlockedSleep)
// continue;
dbgprintf("%w %s(%u) @ %w:%x\n", process->state(), process->name().characters(), process->pid(), process->tss().cs, process->tss().eip);
dbgprintf("% 12s %s(%u) @ %w:%x\n", toString(process->state()), process->name().characters(), process->pid(), process->tss().cs, process->tss().eip);
}
#endif
@ -915,6 +927,10 @@ static bool contextSwitch(Process* t)
current = t;
t->set_state(Process::Running);
#ifdef COOL_GLOBALS
g_cool_globals->current_pid = t->pid();
#endif
if (!t->selector()) {
t->setSelector(gdt_alloc_entry());
auto& descriptor = getGDTEntry(t->selector());