mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 22:07:34 +00:00
Kernel: Finalizer should not go back to sleep if there's more to do
Before putting itself back on the wait queue, the finalizer task will now check if there's more work to do, and if so, do it first. :^) This patch also puts a bunch of process/thread debug logging behind PROCESS_DEBUG and THREAD_DEBUG since it was unbearable to debug this stuff with all the spam.
This commit is contained in:
parent
8d51352b96
commit
934b1d8a9b
5 changed files with 36 additions and 4 deletions
|
@ -73,6 +73,7 @@
|
|||
#include <LibC/signal_numbers.h>
|
||||
#include <LibELF/ELFLoader.h>
|
||||
|
||||
//#define PROCESS_DEBUG
|
||||
//#define DEBUG_POLL_SELECT
|
||||
//#define DEBUG_IO
|
||||
//#define TASK_DEBUG
|
||||
|
@ -1295,7 +1296,9 @@ Process::Process(Thread*& first_thread, const String& name, uid_t uid, gid_t gid
|
|||
, m_tty(tty)
|
||||
, m_ppid(ppid)
|
||||
{
|
||||
#ifdef PROCESS_DEBUG
|
||||
dbg() << "Created new process " << m_name << "(" << m_pid << ")";
|
||||
#endif
|
||||
|
||||
m_page_directory = PageDirectory::create_for_userspace(*this, fork_parent ? &fork_parent->page_directory().range_allocator() : nullptr);
|
||||
#ifdef MM_DEBUG
|
||||
|
@ -2278,7 +2281,9 @@ int Process::reap(Process& process)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef PROCESS_DEBUG
|
||||
dbg() << "Reaping process " << process;
|
||||
#endif
|
||||
ASSERT(process.is_dead());
|
||||
g_processes->remove(&process);
|
||||
}
|
||||
|
@ -2289,7 +2294,10 @@ int Process::reap(Process& process)
|
|||
pid_t Process::sys$waitpid(pid_t waitee, int* wstatus, int options)
|
||||
{
|
||||
REQUIRE_PROMISE(stdio);
|
||||
|
||||
#ifdef PROCESS_DEBUG
|
||||
dbg() << "sys$waitpid(" << waitee << ", " << wstatus << ", " << options << ")";
|
||||
#endif
|
||||
|
||||
if (!options) {
|
||||
// FIXME: This can't be right.. can it? Figure out how this should actually work.
|
||||
|
@ -2928,7 +2936,9 @@ int Process::sys$chown(const Syscall::SC_chown_params* user_params)
|
|||
void Process::finalize()
|
||||
{
|
||||
ASSERT(current == g_finalizer);
|
||||
#ifdef PROCESS_DEBUG
|
||||
dbg() << "Finalizing process " << *this;
|
||||
#endif
|
||||
|
||||
m_fds.clear();
|
||||
m_tty = nullptr;
|
||||
|
|
|
@ -68,6 +68,7 @@ Thread* current;
|
|||
Thread* g_finalizer;
|
||||
Thread* g_colonel;
|
||||
WaitQueue* g_finalizer_wait_queue;
|
||||
bool g_finalizer_has_work;
|
||||
static Process* s_colonel_process;
|
||||
u64 g_uptime;
|
||||
|
||||
|
@ -578,6 +579,7 @@ void Scheduler::initialize()
|
|||
{
|
||||
g_scheduler_data = new SchedulerData;
|
||||
g_finalizer_wait_queue = new WaitQueue;
|
||||
g_finalizer_has_work = false;
|
||||
s_redirection.selector = gdt_alloc_entry();
|
||||
initialize_redirection();
|
||||
s_colonel_process = Process::create_kernel_process(g_colonel, "colonel", nullptr);
|
||||
|
|
|
@ -41,6 +41,7 @@ extern Thread* current;
|
|||
extern Thread* g_finalizer;
|
||||
extern Thread* g_colonel;
|
||||
extern WaitQueue* g_finalizer_wait_queue;
|
||||
extern bool g_finalizer_has_work;
|
||||
extern u64 g_uptime;
|
||||
extern SchedulerData* g_scheduler_data;
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <LibELF/ELFLoader.h>
|
||||
|
||||
//#define SIGNAL_DEBUG
|
||||
//#define THREAD_DEBUG
|
||||
|
||||
static FPUState s_clean_fpu_state;
|
||||
|
||||
|
@ -82,7 +83,9 @@ Thread::Thread(Process& process)
|
|||
m_tid = Process::allocate_pid();
|
||||
}
|
||||
process.m_thread_count++;
|
||||
#ifdef THREAD_DEBUG
|
||||
dbg() << "Created new thread " << process.name() << "(" << process.pid() << ":" << m_tid << ")";
|
||||
#endif
|
||||
set_default_signal_dispositions();
|
||||
m_fpu_state = (FPUState*)kmalloc_aligned(sizeof(FPUState), 16);
|
||||
memcpy(m_fpu_state, &s_clean_fpu_state, sizeof(FPUState));
|
||||
|
@ -163,7 +166,9 @@ void Thread::unblock()
|
|||
void Thread::set_should_die()
|
||||
{
|
||||
if (m_should_die) {
|
||||
dbgprintf("Should already die (%u)\n", m_tid);
|
||||
#ifdef THREAD_DEBUG
|
||||
dbg() << *this << " Should already die";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
InterruptDisabler disabler;
|
||||
|
@ -275,7 +280,9 @@ void Thread::finalize()
|
|||
{
|
||||
ASSERT(current == g_finalizer);
|
||||
|
||||
#ifdef THREAD_DEBUG
|
||||
dbg() << "Finalizing thread " << *this;
|
||||
#endif
|
||||
set_state(Thread::State::Dead);
|
||||
|
||||
if (m_joiner) {
|
||||
|
@ -320,21 +327,25 @@ bool Thread::tick()
|
|||
return --m_ticks_left;
|
||||
}
|
||||
|
||||
void Thread::send_signal(u8 signal, Process* sender)
|
||||
void Thread::send_signal(u8 signal, [[maybe_unused]] Process* sender)
|
||||
{
|
||||
ASSERT(signal < 32);
|
||||
InterruptDisabler disabler;
|
||||
|
||||
// FIXME: Figure out what to do for masked signals. Should we also ignore them here?
|
||||
if (should_ignore_signal(signal)) {
|
||||
#ifdef SIGNAL_DEBUG
|
||||
dbg() << "signal " << signal << " was ignored by " << process();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef SIGNAL_DEBUG
|
||||
if (sender)
|
||||
dbgprintf("signal: %s(%u) sent %d to %s(%u)\n", sender->name().characters(), sender->pid(), signal, process().name().characters(), pid());
|
||||
else
|
||||
dbgprintf("signal: kernel sent %d to %s(%u)\n", signal, process().name().characters(), pid());
|
||||
#endif
|
||||
|
||||
m_pending_signals |= 1 << (signal - 1);
|
||||
}
|
||||
|
@ -707,8 +718,10 @@ void Thread::set_state(State new_state)
|
|||
Scheduler::update_state_for_thread(*this);
|
||||
}
|
||||
|
||||
if (new_state == Dying)
|
||||
if (new_state == Dying) {
|
||||
g_finalizer_has_work = true;
|
||||
g_finalizer_wait_queue->wake_all();
|
||||
}
|
||||
}
|
||||
|
||||
String Thread::backtrace(ProcessInspectionHandle&) const
|
||||
|
|
|
@ -189,7 +189,13 @@ extern "C" [[noreturn]] void init()
|
|||
Process::create_kernel_process(g_finalizer, "Finalizer", [] {
|
||||
current->set_priority(THREAD_PRIORITY_LOW);
|
||||
for (;;) {
|
||||
{
|
||||
InterruptDisabler disabler;
|
||||
if (!g_finalizer_has_work)
|
||||
current->wait_on(*g_finalizer_wait_queue);
|
||||
ASSERT(g_finalizer_has_work);
|
||||
g_finalizer_has_work = false;
|
||||
}
|
||||
Thread::finalize_dying_threads();
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue