mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 22:27:42 +00:00
Way tighter locking in process creation.
We no longer disable interrupts around the whole affair. Since MM manages per-process data structures, this works quite smoothly now. Only procfs had to be tweaked with an InterruptDisabler.
This commit is contained in:
parent
52607aa086
commit
3a901ae36d
3 changed files with 40 additions and 25 deletions
|
@ -116,7 +116,7 @@ ByteBuffer procfs$pid_exe(Process& process)
|
||||||
|
|
||||||
void ProcFileSystem::addProcess(Process& process)
|
void ProcFileSystem::addProcess(Process& process)
|
||||||
{
|
{
|
||||||
ASSERT_INTERRUPTS_DISABLED();
|
InterruptDisabler disabler;
|
||||||
char buf[16];
|
char buf[16];
|
||||||
ksprintf(buf, "%d", process.pid());
|
ksprintf(buf, "%d", process.pid());
|
||||||
auto dir = addFile(createDirectory(buf));
|
auto dir = addFile(createDirectory(buf));
|
||||||
|
@ -130,7 +130,7 @@ void ProcFileSystem::addProcess(Process& process)
|
||||||
|
|
||||||
void ProcFileSystem::removeProcess(Process& process)
|
void ProcFileSystem::removeProcess(Process& process)
|
||||||
{
|
{
|
||||||
ASSERT_INTERRUPTS_DISABLED();
|
InterruptDisabler disabler;
|
||||||
auto pid = process.pid();
|
auto pid = process.pid();
|
||||||
auto it = m_pid2inode.find(pid);
|
auto it = m_pid2inode.find(pid);
|
||||||
ASSERT(it != m_pid2inode.end());
|
ASSERT(it != m_pid2inode.end());
|
||||||
|
|
|
@ -86,13 +86,20 @@ void Process::prepForIRETToNewProcess()
|
||||||
loadTaskRegister(s_kernelProcess->selector());
|
loadTaskRegister(s_kernelProcess->selector());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hlt_loop()
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
asm volatile("hlt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Process::initialize()
|
void Process::initialize()
|
||||||
{
|
{
|
||||||
current = nullptr;
|
current = nullptr;
|
||||||
next_pid = 0;
|
next_pid = 0;
|
||||||
s_processes = new InlineLinkedList<Process>;
|
s_processes = new InlineLinkedList<Process>;
|
||||||
s_deadProcesses = new InlineLinkedList<Process>;
|
s_deadProcesses = new InlineLinkedList<Process>;
|
||||||
s_kernelProcess = Process::createKernelProcess(nullptr, "colonel");
|
s_kernelProcess = Process::createKernelProcess(hlt_loop, "colonel");
|
||||||
s_hostname = new String("birx");
|
s_hostname = new String("birx");
|
||||||
redoKernelProcessTSS();
|
redoKernelProcessTSS();
|
||||||
loadTaskRegister(s_kernelProcess->selector());
|
loadTaskRegister(s_kernelProcess->selector());
|
||||||
|
@ -271,18 +278,16 @@ Process* Process::createUserProcess(const String& path, uid_t uid, gid_t gid, pi
|
||||||
processEnvironment.append("TERM=console");
|
processEnvironment.append("TERM=console");
|
||||||
processEnvironment.append("HOME=/");
|
processEnvironment.append("HOME=/");
|
||||||
|
|
||||||
InterruptDisabler disabler; // FIXME: Get rid of this, jesus christ. This "critical" section is HUGE.
|
auto* t = new Process(parts.takeLast(), uid, gid, parentPID, Ring3, move(cwd), handle->vnode(), tty);
|
||||||
KernelPagingScope pagingScope;
|
|
||||||
Process* t = new Process(parts.takeLast(), uid, gid, parentPID, Ring3, move(cwd), handle->vnode(), tty);
|
|
||||||
|
|
||||||
t->m_arguments = move(processArguments);
|
t->m_arguments = move(processArguments);
|
||||||
t->m_initialEnvironment = move(processEnvironment);
|
t->m_initialEnvironment = move(processEnvironment);
|
||||||
|
|
||||||
ExecSpace space;
|
ExecSpace space;
|
||||||
Region* region = nullptr;
|
Region* region = nullptr;
|
||||||
|
|
||||||
byte* region_alias = nullptr;
|
byte* region_alias = nullptr;
|
||||||
|
|
||||||
|
KernelPagingScope pagingScope;
|
||||||
space.hookableAlloc = [&] (const String& name, size_t size) {
|
space.hookableAlloc = [&] (const String& name, size_t size) {
|
||||||
if (!size)
|
if (!size)
|
||||||
return (void*)nullptr;
|
return (void*)nullptr;
|
||||||
|
@ -330,6 +335,8 @@ Process* Process::createUserProcess(const String& path, uid_t uid, gid_t gid, pi
|
||||||
ASSERT(region);
|
ASSERT(region);
|
||||||
MM.remove_kernel_alias_for_region(*region, region_alias);
|
MM.remove_kernel_alias_for_region(*region, region_alias);
|
||||||
|
|
||||||
|
ProcFileSystem::the().addProcess(*t);
|
||||||
|
|
||||||
s_processes->prepend(t);
|
s_processes->prepend(t);
|
||||||
system.nprocess++;
|
system.nprocess++;
|
||||||
#ifdef TASK_DEBUG
|
#ifdef TASK_DEBUG
|
||||||
|
@ -379,13 +386,14 @@ int Process::sys$get_arguments(int* argc, char*** argv)
|
||||||
|
|
||||||
Process* Process::createKernelProcess(void (*e)(), String&& name)
|
Process* Process::createKernelProcess(void (*e)(), String&& name)
|
||||||
{
|
{
|
||||||
Process* process = new Process(move(name), (uid_t)0, (gid_t)0, (pid_t)0, Ring0);
|
auto* process = new Process(move(name), (uid_t)0, (gid_t)0, (pid_t)0, Ring0);
|
||||||
process->m_tss.eip = (dword)e;
|
process->m_tss.eip = (dword)e;
|
||||||
|
|
||||||
if (process->pid() != 0) {
|
if (process->pid() != 0) {
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
s_processes->prepend(process);
|
s_processes->prepend(process);
|
||||||
system.nprocess++;
|
system.nprocess++;
|
||||||
|
ProcFileSystem::the().addProcess(*process);
|
||||||
#ifdef TASK_DEBUG
|
#ifdef TASK_DEBUG
|
||||||
kprintf("Kernel process %u (%s) spawned @ %p\n", process->pid(), process->name().characters(), process->m_tss.eip);
|
kprintf("Kernel process %u (%s) spawned @ %p\n", process->pid(), process->name().characters(), process->m_tss.eip);
|
||||||
#endif
|
#endif
|
||||||
|
@ -474,8 +482,6 @@ Process::Process(String&& name, uid_t uid, gid_t gid, pid_t parentPID, RingLevel
|
||||||
// HACK: Ring2 SS in the TSS is the current PID.
|
// HACK: Ring2 SS in the TSS is the current PID.
|
||||||
m_tss.ss2 = m_pid;
|
m_tss.ss2 = m_pid;
|
||||||
m_farPtr.offset = 0x98765432;
|
m_farPtr.offset = 0x98765432;
|
||||||
|
|
||||||
ProcFileSystem::the().addProcess(*this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Process::~Process()
|
Process::~Process()
|
||||||
|
@ -707,7 +713,7 @@ bool scheduleNewProcess()
|
||||||
process->timesScheduled(),
|
process->timesScheduled(),
|
||||||
process->name().characters());
|
process->name().characters());
|
||||||
}
|
}
|
||||||
kprintf("Switch to kernel process\n");
|
kprintf("Switch to kernel process @ %w:%x\n", s_kernelProcess->tss().cs, s_kernelProcess->tss().eip);
|
||||||
return contextSwitch(Process::kernelProcess());
|
return contextSwitch(Process::kernelProcess());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,25 @@ static void undertaker_main()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void spawn_stress() NORETURN;
|
||||||
|
static void spawn_stress()
|
||||||
|
{
|
||||||
|
dword lastAlloc = sum_alloc;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < 100; ++i) {
|
||||||
|
int error;
|
||||||
|
Process::createUserProcess("/bin/id", (uid_t)100, (gid_t)100, (pid_t)0, error, nullptr, tty0);
|
||||||
|
kprintf("malloc stats: alloc:%u free:%u\n", sum_alloc, sum_free);
|
||||||
|
kprintf("delta:%u\n", sum_alloc - lastAlloc);
|
||||||
|
lastAlloc = sum_alloc;
|
||||||
|
sleep(600);
|
||||||
|
}
|
||||||
|
for (;;) {
|
||||||
|
asm volatile("hlt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void init_stage2() NORETURN;
|
static void init_stage2() NORETURN;
|
||||||
static void init_stage2()
|
static void init_stage2()
|
||||||
{
|
{
|
||||||
|
@ -173,20 +192,6 @@ static void init_stage2()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef STRESS_TEST_SPAWNING
|
|
||||||
dword lastAlloc = sum_alloc;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < 100; ++i) {
|
|
||||||
int error;
|
|
||||||
auto* shProcess = Process::createUserProcess("/bin/id", (uid_t)100, (gid_t)100, (pid_t)0, error);
|
|
||||||
kprintf("malloc stats: alloc:%u free:%u\n", sum_alloc, sum_free);
|
|
||||||
kprintf("sizeof(Process):%u\n", sizeof(Process));
|
|
||||||
kprintf("delta:%u\n",sum_alloc - lastAlloc);
|
|
||||||
lastAlloc = sum_alloc;
|
|
||||||
sleep(600);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int error;
|
int error;
|
||||||
auto* sh0 = Process::createUserProcess("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, nullptr, tty0);
|
auto* sh0 = Process::createUserProcess("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, nullptr, tty0);
|
||||||
#ifdef SPAWN_MULTIPLE_SHELLS
|
#ifdef SPAWN_MULTIPLE_SHELLS
|
||||||
|
@ -195,6 +200,10 @@ static void init_stage2()
|
||||||
auto* sh3 = Process::createUserProcess("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, nullptr, tty3);
|
auto* sh3 = Process::createUserProcess("/bin/sh", (uid_t)100, (gid_t)100, (pid_t)0, error, nullptr, tty3);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef STRESS_TEST_SPAWNING
|
||||||
|
Process::createKernelProcess(spawn_stress, "spawn_stress");
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// It would be nice to exit this process, but right now it instantiates all kinds of things.
|
// It would be nice to exit this process, but right now it instantiates all kinds of things.
|
||||||
// At the very least it needs to be made sure those things stick around as appropriate.
|
// At the very least it needs to be made sure those things stick around as appropriate.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue