mirror of
https://github.com/RGBCube/serenity
synced 2025-05-16 19:55:06 +00:00
Some refactor and style tweaks.
This commit is contained in:
parent
03a8357e84
commit
6304c771dd
7 changed files with 103 additions and 113 deletions
|
@ -52,11 +52,11 @@ CoolGlobals* g_cool_globals;
|
||||||
static const DWORD defaultStackSize = 16384;
|
static const DWORD defaultStackSize = 16384;
|
||||||
|
|
||||||
Process* current;
|
Process* current;
|
||||||
Process* s_kernelProcess;
|
Process* s_colonel_process;
|
||||||
|
|
||||||
static pid_t next_pid;
|
static pid_t next_pid;
|
||||||
static InlineLinkedList<Process>* s_processes;
|
static InlineLinkedList<Process>* s_processes;
|
||||||
static InlineLinkedList<Process>* s_deadProcesses;
|
static InlineLinkedList<Process>* s_dead_processes;
|
||||||
static String* s_hostname;
|
static String* s_hostname;
|
||||||
|
|
||||||
static String& hostnameStorage(InterruptDisabler&)
|
static String& hostnameStorage(InterruptDisabler&)
|
||||||
|
@ -73,14 +73,14 @@ static String getHostname()
|
||||||
|
|
||||||
static bool contextSwitch(Process*);
|
static bool contextSwitch(Process*);
|
||||||
|
|
||||||
static void redoKernelProcessTSS()
|
static void redo_colonel_process_tss()
|
||||||
{
|
{
|
||||||
if (!s_kernelProcess->selector())
|
if (!s_colonel_process->selector())
|
||||||
s_kernelProcess->setSelector(gdt_alloc_entry());
|
s_colonel_process->setSelector(gdt_alloc_entry());
|
||||||
|
|
||||||
auto& tssDescriptor = getGDTEntry(s_kernelProcess->selector());
|
auto& tssDescriptor = getGDTEntry(s_colonel_process->selector());
|
||||||
|
|
||||||
tssDescriptor.setBase(&s_kernelProcess->tss());
|
tssDescriptor.setBase(&s_colonel_process->tss());
|
||||||
tssDescriptor.setLimit(0xffff);
|
tssDescriptor.setLimit(0xffff);
|
||||||
tssDescriptor.dpl = 0;
|
tssDescriptor.dpl = 0;
|
||||||
tssDescriptor.segment_present = 1;
|
tssDescriptor.segment_present = 1;
|
||||||
|
@ -93,11 +93,11 @@ static void redoKernelProcessTSS()
|
||||||
flushGDT();
|
flushGDT();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process::prepForIRETToNewProcess()
|
void Process::prepare_for_iret_to_new_process()
|
||||||
{
|
{
|
||||||
redoKernelProcessTSS();
|
redo_colonel_process_tss();
|
||||||
s_kernelProcess->tss().backlink = current->selector();
|
s_colonel_process->tss().backlink = current->selector();
|
||||||
loadTaskRegister(s_kernelProcess->selector());
|
load_task_register(s_colonel_process->selector());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hlt_loop()
|
static void hlt_loop()
|
||||||
|
@ -115,30 +115,11 @@ 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_dead_processes = new InlineLinkedList<Process>;
|
||||||
s_kernelProcess = Process::createKernelProcess(hlt_loop, "colonel");
|
s_colonel_process = Process::create_kernel_process(hlt_loop, "colonel");
|
||||||
s_hostname = new String("birx");
|
s_hostname = new String("birx");
|
||||||
redoKernelProcessTSS();
|
redo_colonel_process_tss();
|
||||||
loadTaskRegister(s_kernelProcess->selector());
|
load_task_register(s_colonel_process->selector());
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Callback>
|
|
||||||
static void forEachProcess(Callback callback)
|
|
||||||
{
|
|
||||||
ASSERT_INTERRUPTS_DISABLED();
|
|
||||||
for (auto* process = s_processes->head(); process; process = process->next()) {
|
|
||||||
if (!callback(*process))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Process::for_each_in_pgrp(pid_t pgid, Function<void(Process&)> callback)
|
|
||||||
{
|
|
||||||
ASSERT_INTERRUPTS_DISABLED();
|
|
||||||
for (auto* process = s_processes->head(); process; process = process->next()) {
|
|
||||||
if (process->pgid() == pgid)
|
|
||||||
callback(*process);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<Process*> Process::allProcesses()
|
Vector<Process*> Process::allProcesses()
|
||||||
|
@ -356,7 +337,7 @@ int Process::exec(const String& path, Vector<String>&& arguments, Vector<String>
|
||||||
|
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
if (current == this)
|
if (current == this)
|
||||||
loadTaskRegister(s_kernelProcess->selector());
|
load_task_register(s_colonel_process->selector());
|
||||||
|
|
||||||
m_name = parts.takeLast();
|
m_name = parts.takeLast();
|
||||||
|
|
||||||
|
@ -484,7 +465,7 @@ Process* Process::create_user_process(const String& path, uid_t uid, gid_t gid,
|
||||||
RetainPtr<VirtualFileSystem::Node> cwd;
|
RetainPtr<VirtualFileSystem::Node> cwd;
|
||||||
{
|
{
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
if (auto* parent = Process::fromPID(parent_pid))
|
if (auto* parent = Process::from_pid(parent_pid))
|
||||||
cwd = parent->m_cwd.copyRef();
|
cwd = parent->m_cwd.copyRef();
|
||||||
}
|
}
|
||||||
if (!cwd)
|
if (!cwd)
|
||||||
|
@ -545,7 +526,7 @@ int Process::sys$get_arguments(int* argc, char*** argv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process* Process::createKernelProcess(void (*e)(), String&& name)
|
Process* Process::create_kernel_process(void (*e)(), String&& name)
|
||||||
{
|
{
|
||||||
auto* 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;
|
||||||
|
@ -585,7 +566,7 @@ Process::Process(String&& name, uid_t uid, gid_t gid, pid_t ppid, RingLevel ring
|
||||||
} else {
|
} else {
|
||||||
// FIXME: Use a ProcessHandle? Presumably we're executing *IN* the parent right now though..
|
// FIXME: Use a ProcessHandle? Presumably we're executing *IN* the parent right now though..
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
if (auto* parent = Process::fromPID(m_ppid)) {
|
if (auto* parent = Process::from_pid(m_ppid)) {
|
||||||
m_sid = parent->m_sid;
|
m_sid = parent->m_sid;
|
||||||
m_pgid = parent->m_pgid;
|
m_pgid = parent->m_pgid;
|
||||||
}
|
}
|
||||||
|
@ -789,8 +770,6 @@ void Process::dispatch_signal(byte signal)
|
||||||
kprintf("resume tss pc: %w:%x\n", m_tss_to_resume_kernel.cs, m_tss_to_resume_kernel.eip);
|
kprintf("resume tss pc: %w:%x\n", m_tss_to_resume_kernel.cs, m_tss_to_resume_kernel.eip);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
word ret_ss = m_tss.ss;
|
|
||||||
dword ret_esp = m_tss.esp;
|
|
||||||
word ret_cs = m_tss.cs;
|
word ret_cs = m_tss.cs;
|
||||||
dword ret_eip = m_tss.eip;
|
dword ret_eip = m_tss.eip;
|
||||||
dword ret_eflags = m_tss.eflags;
|
dword ret_eflags = m_tss.eflags;
|
||||||
|
@ -891,7 +870,7 @@ void Process::sys$sigreturn()
|
||||||
dbgprintf("sys$sigreturn in %s(%u)\n", name().characters(), pid());
|
dbgprintf("sys$sigreturn in %s(%u)\n", name().characters(), pid());
|
||||||
dbgprintf(" -> resuming execution at %w:%x\n", m_tss.cs, m_tss.eip);
|
dbgprintf(" -> resuming execution at %w:%x\n", m_tss.cs, m_tss.eip);
|
||||||
#endif
|
#endif
|
||||||
loadTaskRegister(s_kernelProcess->selector());
|
load_task_register(s_colonel_process->selector());
|
||||||
sched_yield();
|
sched_yield();
|
||||||
kprintf("sys$sigreturn failed in %s(%u)\n", name().characters(), pid());
|
kprintf("sys$sigreturn failed in %s(%u)\n", name().characters(), pid());
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
|
@ -922,15 +901,15 @@ void Process::crash()
|
||||||
|
|
||||||
void Process::doHouseKeeping()
|
void Process::doHouseKeeping()
|
||||||
{
|
{
|
||||||
if (s_deadProcesses->isEmpty())
|
if (s_dead_processes->isEmpty())
|
||||||
return;
|
return;
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
Process* next = nullptr;
|
Process* next = nullptr;
|
||||||
for (auto* deadProcess = s_deadProcesses->head(); deadProcess; deadProcess = next) {
|
for (auto* deadProcess = s_dead_processes->head(); deadProcess; deadProcess = next) {
|
||||||
next = deadProcess->next();
|
next = deadProcess->next();
|
||||||
delete deadProcess;
|
delete deadProcess;
|
||||||
}
|
}
|
||||||
s_deadProcesses->clear();
|
s_dead_processes->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
int sched_yield()
|
int sched_yield()
|
||||||
|
@ -962,8 +941,27 @@ void switchNow()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Callback>
|
void Process::for_each(Function<bool(Process&)> callback)
|
||||||
static void for_each_process_in_state(Process::State state, Callback callback)
|
{
|
||||||
|
ASSERT_INTERRUPTS_DISABLED();
|
||||||
|
for (auto* process = s_processes->head(); process; process = process->next()) {
|
||||||
|
if (!callback(*process))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Process::for_each_in_pgrp(pid_t pgid, Function<bool(Process&)> callback)
|
||||||
|
{
|
||||||
|
ASSERT_INTERRUPTS_DISABLED();
|
||||||
|
for (auto* process = s_processes->head(); process; process = process->next()) {
|
||||||
|
if (process->pgid() == pgid) {
|
||||||
|
if (!callback(*process))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Process::for_each_in_state(State state, Function<bool(Process&)> callback)
|
||||||
{
|
{
|
||||||
ASSERT_INTERRUPTS_DISABLED();
|
ASSERT_INTERRUPTS_DISABLED();
|
||||||
for (auto* process = s_processes->head(); process;) {
|
for (auto* process = s_processes->head(); process;) {
|
||||||
|
@ -974,8 +972,7 @@ static void for_each_process_in_state(Process::State state, Callback callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Callback>
|
void Process::for_each_not_in_state(State state, Function<bool(Process&)> callback)
|
||||||
static void for_each_process_not_in_state(Process::State state, Callback callback)
|
|
||||||
{
|
{
|
||||||
ASSERT_INTERRUPTS_DISABLED();
|
ASSERT_INTERRUPTS_DISABLED();
|
||||||
for (auto* process = s_processes->head(); process;) {
|
for (auto* process = s_processes->head(); process;) {
|
||||||
|
@ -986,18 +983,6 @@ static void for_each_process_not_in_state(Process::State state, Callback callbac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Callback>
|
|
||||||
static void for_each_blocked_process(Callback callback)
|
|
||||||
{
|
|
||||||
ASSERT_INTERRUPTS_DISABLED();
|
|
||||||
for (auto* process = s_processes->head(); process;) {
|
|
||||||
auto* next_process = process->next();
|
|
||||||
if (process->is_blocked())
|
|
||||||
callback(*process);
|
|
||||||
process = next_process;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool scheduleNewProcess()
|
bool scheduleNewProcess()
|
||||||
{
|
{
|
||||||
ASSERT_INTERRUPTS_DISABLED();
|
ASSERT_INTERRUPTS_DISABLED();
|
||||||
|
@ -1005,59 +990,62 @@ bool scheduleNewProcess()
|
||||||
if (!current) {
|
if (!current) {
|
||||||
// XXX: The first ever context_switch() goes to the idle process.
|
// XXX: The first ever context_switch() goes to the idle process.
|
||||||
// This to setup a reliable place we can return to.
|
// This to setup a reliable place we can return to.
|
||||||
return contextSwitch(Process::kernelProcess());
|
return contextSwitch(Process::colonel_process());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check and unblock processes whose wait conditions have been met.
|
// Check and unblock processes whose wait conditions have been met.
|
||||||
for (auto* process = s_processes->head(); process; process = process->next()) {
|
Process::for_each([] (auto& process) {
|
||||||
if (process->state() == Process::BlockedSleep) {
|
if (process.state() == Process::BlockedSleep) {
|
||||||
if (process->wakeupTime() <= system.uptime)
|
if (process.wakeupTime() <= system.uptime)
|
||||||
process->unblock();
|
process.unblock();
|
||||||
continue;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process->state() == Process::BlockedWait) {
|
if (process.state() == Process::BlockedWait) {
|
||||||
auto* waitee = Process::fromPID(process->waitee());
|
auto* waitee = Process::from_pid(process.waitee());
|
||||||
if (!waitee) {
|
if (!waitee) {
|
||||||
kprintf("waitee %u of %s(%u) reaped before I could wait?\n", process->waitee(), process->name().characters(), process->pid());
|
kprintf("waitee %u of %s(%u) reaped before I could wait?\n", process.waitee(), process.name().characters(), process.pid());
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
if (waitee->state() == Process::Dead) {
|
if (waitee->state() == Process::Dead) {
|
||||||
process->m_waitee_status = (waitee->m_termination_status << 8) | waitee->m_termination_signal;
|
process.m_waitee_status = (waitee->m_termination_status << 8) | waitee->m_termination_signal;
|
||||||
process->unblock();
|
process.unblock();
|
||||||
waitee->set_state(Process::Forgiven);
|
waitee->set_state(Process::Forgiven);
|
||||||
}
|
}
|
||||||
continue;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process->state() == Process::BlockedRead) {
|
if (process.state() == Process::BlockedRead) {
|
||||||
ASSERT(process->m_fdBlockedOnRead != -1);
|
ASSERT(process.m_fdBlockedOnRead != -1);
|
||||||
// FIXME: Block until the amount of data wanted is available.
|
// FIXME: Block until the amount of data wanted is available.
|
||||||
if (process->m_file_descriptors[process->m_fdBlockedOnRead]->hasDataAvailableForRead())
|
if (process.m_file_descriptors[process.m_fdBlockedOnRead]->hasDataAvailableForRead())
|
||||||
process->unblock();
|
process.unblock();
|
||||||
continue;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
// Forgive dead orphans.
|
// Forgive dead orphans.
|
||||||
// FIXME: Does this really make sense?
|
// FIXME: Does this really make sense?
|
||||||
for_each_process_in_state(Process::Dead, [] (auto& process) {
|
Process::for_each_in_state(Process::Dead, [] (auto& process) {
|
||||||
if (!Process::fromPID(process.ppid()))
|
if (!Process::from_pid(process.ppid()))
|
||||||
process.set_state(Process::Forgiven);
|
process.set_state(Process::Forgiven);
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Clean up forgiven processes.
|
// Clean up forgiven processes.
|
||||||
// FIXME: Do we really need this to be a separate pass over the process list?
|
// FIXME: Do we really need this to be a separate pass over the process list?
|
||||||
for_each_process_in_state(Process::Forgiven, [] (auto& process) {
|
Process::for_each_in_state(Process::Forgiven, [] (auto& process) {
|
||||||
s_processes->remove(&process);
|
s_processes->remove(&process);
|
||||||
s_deadProcesses->append(&process);
|
s_dead_processes->append(&process);
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Dispatch any pending signals.
|
// Dispatch any pending signals.
|
||||||
// FIXME: Do we really need this to be a separate pass over the process list?
|
// FIXME: Do we really need this to be a separate pass over the process list?
|
||||||
for_each_process_not_in_state(Process::Dead, [] (auto& process) {
|
Process::for_each_not_in_state(Process::Dead, [] (auto& process) {
|
||||||
if (!process.has_unmasked_pending_signals())
|
if (!process.has_unmasked_pending_signals())
|
||||||
return;
|
return true;
|
||||||
// We know how to interrupt blocked processes, but if they are just executing
|
// We know how to interrupt blocked processes, but if they are just executing
|
||||||
// at some random point in the kernel, let them continue. They'll be in userspace
|
// at some random point in the kernel, let them continue. They'll be in userspace
|
||||||
// sooner or later and we can deliver the signal then.
|
// sooner or later and we can deliver the signal then.
|
||||||
|
@ -1065,12 +1053,13 @@ bool scheduleNewProcess()
|
||||||
// signal and dispatch it then and there? Would that be doable without the
|
// signal and dispatch it then and there? Would that be doable without the
|
||||||
// syscall effectively being "interrupted" despite having completed?
|
// syscall effectively being "interrupted" despite having completed?
|
||||||
if (process.in_kernel() && !process.is_blocked())
|
if (process.in_kernel() && !process.is_blocked())
|
||||||
return;
|
return true;
|
||||||
process.dispatch_one_pending_signal();
|
process.dispatch_one_pending_signal();
|
||||||
if (process.is_blocked()) {
|
if (process.is_blocked()) {
|
||||||
process.m_was_interrupted_while_blocked = true;
|
process.m_was_interrupted_while_blocked = true;
|
||||||
process.unblock();
|
process.unblock();
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
#ifdef SCHEDULER_DEBUG
|
#ifdef SCHEDULER_DEBUG
|
||||||
|
@ -1108,8 +1097,8 @@ bool scheduleNewProcess()
|
||||||
process->timesScheduled(),
|
process->timesScheduled(),
|
||||||
process->name().characters());
|
process->name().characters());
|
||||||
}
|
}
|
||||||
kprintf("Switch to kernel process @ %w:%x\n", s_kernelProcess->tss().cs, s_kernelProcess->tss().eip);
|
kprintf("Switch to kernel process @ %w:%x\n", s_colonel_process->tss().cs, s_colonel_process->tss().eip);
|
||||||
return contextSwitch(Process::kernelProcess());
|
return contextSwitch(Process::colonel_process());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1171,7 +1160,7 @@ static bool contextSwitch(Process* t)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process* Process::fromPID(pid_t pid)
|
Process* Process::from_pid(pid_t pid)
|
||||||
{
|
{
|
||||||
ASSERT_INTERRUPTS_DISABLED();
|
ASSERT_INTERRUPTS_DISABLED();
|
||||||
for (auto* process = s_processes->head(); process; process = process->next()) {
|
for (auto* process = s_processes->head(); process; process = process->next()) {
|
||||||
|
@ -1425,7 +1414,7 @@ int Process::sys$kill(pid_t pid, int signal)
|
||||||
}
|
}
|
||||||
ASSERT(pid != current->pid()); // FIXME: Support this scenario.
|
ASSERT(pid != current->pid()); // FIXME: Support this scenario.
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
auto* peer = Process::fromPID(pid);
|
auto* peer = Process::from_pid(pid);
|
||||||
if (!peer)
|
if (!peer)
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
peer->send_signal(signal, this);
|
peer->send_signal(signal, this);
|
||||||
|
@ -1498,7 +1487,7 @@ pid_t Process::sys$waitpid(pid_t waitee, int* wstatus, int options)
|
||||||
VALIDATE_USER_WRITE(wstatus, sizeof(int));
|
VALIDATE_USER_WRITE(wstatus, sizeof(int));
|
||||||
|
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
if (!Process::fromPID(waitee))
|
if (!Process::from_pid(waitee))
|
||||||
return -1;
|
return -1;
|
||||||
m_waitee = waitee;
|
m_waitee = waitee;
|
||||||
m_waitee_status = 0;
|
m_waitee_status = 0;
|
||||||
|
@ -1540,10 +1529,10 @@ void sleep(DWORD ticks)
|
||||||
sched_yield();
|
sched_yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
Process* Process::kernelProcess()
|
Process* Process::colonel_process()
|
||||||
{
|
{
|
||||||
ASSERT(s_kernelProcess);
|
ASSERT(s_colonel_process);
|
||||||
return s_kernelProcess;
|
return s_colonel_process;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Process::isValidAddressForKernel(LinearAddress laddr) const
|
bool Process::isValidAddressForKernel(LinearAddress laddr) const
|
||||||
|
@ -1576,7 +1565,7 @@ pid_t Process::sys$getsid(pid_t pid)
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
return m_sid;
|
return m_sid;
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
auto* process = Process::fromPID(pid);
|
auto* process = Process::from_pid(pid);
|
||||||
if (!process)
|
if (!process)
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
if (m_sid != process->m_sid)
|
if (m_sid != process->m_sid)
|
||||||
|
@ -1588,12 +1577,9 @@ pid_t Process::sys$setsid()
|
||||||
{
|
{
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
bool found_process_with_same_pgid_as_my_pid = false;
|
bool found_process_with_same_pgid_as_my_pid = false;
|
||||||
forEachProcess([&] (auto& process) {
|
Process::for_each_in_pgrp(pid(), [&] (auto& process) {
|
||||||
if (process.pgid() == pid()) {
|
found_process_with_same_pgid_as_my_pid = true;
|
||||||
found_process_with_same_pgid_as_my_pid = true;
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
});
|
||||||
if (found_process_with_same_pgid_as_my_pid)
|
if (found_process_with_same_pgid_as_my_pid)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
@ -1607,7 +1593,7 @@ pid_t Process::sys$getpgid(pid_t pid)
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
return m_pgid;
|
return m_pgid;
|
||||||
InterruptDisabler disabler; // FIXME: Use a ProcessHandle
|
InterruptDisabler disabler; // FIXME: Use a ProcessHandle
|
||||||
auto* process = Process::fromPID(pid);
|
auto* process = Process::from_pid(pid);
|
||||||
if (!process)
|
if (!process)
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
return process->m_pgid;
|
return process->m_pgid;
|
||||||
|
@ -1621,7 +1607,7 @@ pid_t Process::sys$getpgrp()
|
||||||
static pid_t get_sid_from_pgid(pid_t pgid)
|
static pid_t get_sid_from_pgid(pid_t pgid)
|
||||||
{
|
{
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
auto* group_leader = Process::fromPID(pgid);
|
auto* group_leader = Process::from_pid(pgid);
|
||||||
if (!group_leader)
|
if (!group_leader)
|
||||||
return -1;
|
return -1;
|
||||||
return group_leader->sid();
|
return group_leader->sid();
|
||||||
|
@ -1633,7 +1619,7 @@ int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
|
||||||
pid_t pid = specified_pid ? specified_pid : m_pid;
|
pid_t pid = specified_pid ? specified_pid : m_pid;
|
||||||
if (specified_pgid < 0)
|
if (specified_pgid < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
auto* process = Process::fromPID(pid);
|
auto* process = Process::from_pid(pid);
|
||||||
if (!process)
|
if (!process)
|
||||||
return -ESRCH;
|
return -ESRCH;
|
||||||
pid_t new_pgid = specified_pgid ? specified_pgid : process->m_pid;
|
pid_t new_pgid = specified_pgid ? specified_pgid : process->m_pid;
|
||||||
|
|
|
@ -25,7 +25,7 @@ struct SignalActionData {
|
||||||
class Process : public InlineLinkedListNode<Process> {
|
class Process : public InlineLinkedListNode<Process> {
|
||||||
friend class InlineLinkedListNode<Process>;
|
friend class InlineLinkedListNode<Process>;
|
||||||
public:
|
public:
|
||||||
static Process* createKernelProcess(void (*entry)(), String&& name);
|
static Process* create_kernel_process(void (*entry)(), String&& name);
|
||||||
static Process* create_user_process(const String& path, uid_t, gid_t, pid_t ppid, int& error, Vector<String>&& arguments = Vector<String>(), Vector<String>&& environment = Vector<String>(), TTY* = nullptr);
|
static Process* create_user_process(const String& path, uid_t, gid_t, pid_t ppid, int& error, Vector<String>&& arguments = Vector<String>(), Vector<String>&& environment = Vector<String>(), TTY* = nullptr);
|
||||||
~Process();
|
~Process();
|
||||||
|
|
||||||
|
@ -58,8 +58,8 @@ public:
|
||||||
|
|
||||||
bool in_kernel() const { return (m_tss.cs & 0x03) == 0; }
|
bool in_kernel() const { return (m_tss.cs & 0x03) == 0; }
|
||||||
|
|
||||||
static Process* fromPID(pid_t);
|
static Process* from_pid(pid_t);
|
||||||
static Process* kernelProcess();
|
static Process* colonel_process();
|
||||||
|
|
||||||
const String& name() const { return m_name; }
|
const String& name() const { return m_name; }
|
||||||
pid_t pid() const { return m_pid; }
|
pid_t pid() const { return m_pid; }
|
||||||
|
@ -88,9 +88,12 @@ public:
|
||||||
void setWakeupTime(DWORD t) { m_wakeupTime = t; }
|
void setWakeupTime(DWORD t) { m_wakeupTime = t; }
|
||||||
DWORD wakeupTime() const { return m_wakeupTime; }
|
DWORD wakeupTime() const { return m_wakeupTime; }
|
||||||
|
|
||||||
static void for_each_in_pgrp(pid_t pgid, Function<void(Process&)>);
|
static void for_each(Function<bool(Process&)>);
|
||||||
|
static void for_each_in_pgrp(pid_t, Function<bool(Process&)>);
|
||||||
|
static void for_each_in_state(State, Function<bool(Process&)>);
|
||||||
|
static void for_each_not_in_state(State, Function<bool(Process&)>);
|
||||||
|
|
||||||
static void prepForIRETToNewProcess();
|
static void prepare_for_iret_to_new_process();
|
||||||
|
|
||||||
bool tick() { ++m_ticks; return --m_ticksLeft; }
|
bool tick() { ++m_ticks; return --m_ticksLeft; }
|
||||||
void setTicksLeft(DWORD t) { m_ticksLeft = t; }
|
void setTicksLeft(DWORD t) { m_ticksLeft = t; }
|
||||||
|
|
|
@ -50,6 +50,7 @@ void TTY::interrupt()
|
||||||
Process::for_each_in_pgrp(pgid(), [this] (auto& process) {
|
Process::for_each_in_pgrp(pgid(), [this] (auto& process) {
|
||||||
dbgprintf("%s: Send SIGINT to %d\n", ttyName().characters(), process.pid());
|
dbgprintf("%s: Send SIGINT to %d\n", ttyName().characters(), process.pid());
|
||||||
process.send_signal(SIGINT, nullptr);
|
process.send_signal(SIGINT, nullptr);
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -414,7 +414,7 @@ void idt_init()
|
||||||
flushIDT();
|
flushIDT();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadTaskRegister(WORD selector)
|
void load_task_register(WORD selector)
|
||||||
{
|
{
|
||||||
asm("ltr %0"::"r"(selector));
|
asm("ltr %0"::"r"(selector));
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ void registerIRQHandler(BYTE number, IRQHandler&);
|
||||||
void unregisterIRQHandler(BYTE number, IRQHandler&);
|
void unregisterIRQHandler(BYTE number, IRQHandler&);
|
||||||
void flushIDT();
|
void flushIDT();
|
||||||
void flushGDT();
|
void flushGDT();
|
||||||
void loadTaskRegister(WORD selector);
|
void load_task_register(WORD selector);
|
||||||
word gdt_alloc_entry();
|
word gdt_alloc_entry();
|
||||||
void gdt_free_entry(word);
|
void gdt_free_entry(word);
|
||||||
Descriptor& getGDTEntry(WORD selector);
|
Descriptor& getGDTEntry(WORD selector);
|
||||||
|
|
|
@ -105,7 +105,7 @@ void clock_handle()
|
||||||
|
|
||||||
if (!scheduleNewProcess())
|
if (!scheduleNewProcess())
|
||||||
return;
|
return;
|
||||||
Process::prepForIRETToNewProcess();
|
Process::prepare_for_iret_to_new_process();
|
||||||
|
|
||||||
// Set the NT (nested task) flag.
|
// Set the NT (nested task) flag.
|
||||||
asm(
|
asm(
|
||||||
|
|
|
@ -308,8 +308,8 @@ void init()
|
||||||
|
|
||||||
Process::initialize();
|
Process::initialize();
|
||||||
|
|
||||||
Process::createKernelProcess(undertaker_main, "undertaker");
|
Process::create_kernel_process(undertaker_main, "undertaker");
|
||||||
Process::createKernelProcess(init_stage2, "init");
|
Process::create_kernel_process(init_stage2, "init");
|
||||||
|
|
||||||
scheduleNewProcess();
|
scheduleNewProcess();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue