1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-10 08:57:35 +00:00

Kernel: Make Thread refcounted

Similar to Process, we need to make Thread refcounted. This will solve
problems that will appear once we schedule threads on more than one
processor. This allows us to hold onto threads without necessarily
holding the scheduler lock for the entire duration.
This commit is contained in:
Tom 2020-09-27 08:53:35 -06:00 committed by Andreas Kling
parent 079486ed7e
commit 838d9fa251
14 changed files with 136 additions and 90 deletions

View file

@ -265,7 +265,7 @@ void Process::kill_all_threads()
});
}
RefPtr<Process> Process::create_user_process(Thread*& first_thread, const String& path, uid_t uid, gid_t gid, ProcessID parent_pid, int& error, Vector<String>&& arguments, Vector<String>&& environment, TTY* tty)
RefPtr<Process> Process::create_user_process(RefPtr<Thread>& first_thread, const String& path, uid_t uid, gid_t gid, ProcessID parent_pid, int& error, Vector<String>&& arguments, Vector<String>&& environment, TTY* tty)
{
auto parts = path.split('/');
if (arguments.is_empty()) {
@ -298,7 +298,7 @@ RefPtr<Process> Process::create_user_process(Thread*& first_thread, const String
error = process->exec(path, move(arguments), move(environment));
if (error != 0) {
dbg() << "Failed to exec " << path << ": " << error;
delete first_thread;
first_thread = nullptr;
return {};
}
@ -311,7 +311,7 @@ RefPtr<Process> Process::create_user_process(Thread*& first_thread, const String
return process;
}
NonnullRefPtr<Process> Process::create_kernel_process(Thread*& first_thread, String&& name, void (*e)(), u32 affinity)
NonnullRefPtr<Process> Process::create_kernel_process(RefPtr<Thread>& first_thread, String&& name, void (*e)(), u32 affinity)
{
auto process = adopt(*new Process(first_thread, move(name), (uid_t)0, (gid_t)0, ProcessID(0), true));
first_thread->tss().eip = (FlatPtr)e;
@ -327,7 +327,7 @@ NonnullRefPtr<Process> Process::create_kernel_process(Thread*& first_thread, Str
return process;
}
Process::Process(Thread*& first_thread, const String& name, uid_t uid, gid_t gid, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> cwd, RefPtr<Custody> executable, TTY* tty, Process* fork_parent)
Process::Process(RefPtr<Thread>& first_thread, const String& name, uid_t uid, gid_t gid, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> cwd, RefPtr<Custody> executable, TTY* tty, Process* fork_parent)
: m_name(move(name))
, m_pid(allocate_pid())
, m_euid(uid)
@ -356,14 +356,15 @@ Process::Process(Thread*& first_thread, const String& name, uid_t uid, gid_t gid
first_thread = Thread::current()->clone(*this);
} else {
// NOTE: This non-forked code path is only taken when the kernel creates a process "manually" (at boot.)
first_thread = new Thread(*this);
first_thread = adopt(*new Thread(*this));
first_thread->detach();
}
}
Process::~Process()
{
ASSERT(thread_count() == 0);
ASSERT(!m_next && !m_prev); // should have been reaped
ASSERT(thread_count() == 0); // all threads should have been finalized
}
void Process::dump_regions()
@ -613,7 +614,7 @@ void Process::finalize()
{
InterruptDisabler disabler;
// FIXME: PID/TID BUG
if (auto* parent_thread = Thread::from_tid(m_ppid.value())) {
if (auto parent_thread = Thread::from_tid(m_ppid.value())) {
if (parent_thread->m_signal_action_data[SIGCHLD].flags & SA_NOCLDWAIT) {
// NOTE: If the parent doesn't care about this process, let it go.
m_ppid = 0;
@ -761,13 +762,13 @@ KResult Process::send_signal(u8 signal, Process* sender)
return KResult(-ESRCH);
}
Thread* Process::create_kernel_thread(void (*entry)(), u32 priority, const String& name, u32 affinity, bool joinable)
RefPtr<Thread> Process::create_kernel_thread(void (*entry)(), u32 priority, const String& name, u32 affinity, bool joinable)
{
ASSERT((priority >= THREAD_PRIORITY_MIN) && (priority <= THREAD_PRIORITY_MAX));
// FIXME: Do something with guard pages?
auto* thread = new Thread(*this);
auto thread = adopt(*new Thread(*this));
thread->set_name(name);
thread->set_affinity(affinity);