diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 2e219f7612..40a280c4c1 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1207,8 +1207,16 @@ int Process::sys$setgid(gid_t gid) unsigned Process::sys$alarm(unsigned seconds) { - (void) seconds; - ASSERT_NOT_REACHED(); + unsigned previous_alarm_remaining = 0; + if (m_alarm_deadline && m_alarm_deadline > g_uptime) { + previous_alarm_remaining = (m_alarm_deadline - g_uptime) / TICKS_PER_SECOND; + } + if (!seconds) { + m_alarm_deadline = 0; + return previous_alarm_remaining; + } + m_alarm_deadline = g_uptime + seconds * TICKS_PER_SECOND; + return previous_alarm_remaining; } int Process::sys$uname(utsname* buf) diff --git a/Kernel/Process.h b/Kernel/Process.h index a792e5a2a2..e5864b3769 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -351,6 +351,8 @@ private: OwnPtr m_elf_loader; Lock m_big_lock { "Process" }; + + qword m_alarm_deadline { 0 }; }; class ProcessInspectionHandle { @@ -396,7 +398,7 @@ inline void Process::for_each(Callback callback) ASSERT_INTERRUPTS_DISABLED(); for (auto* process = g_processes->head(); process;) { auto* next_process = process->next(); - if (!callback(*process)) + if (callback(*process) == IterationDecision::Abort) break; process = next_process; } diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp index 5063f157e7..8c4b4fa167 100644 --- a/Kernel/Scheduler.cpp +++ b/Kernel/Scheduler.cpp @@ -188,8 +188,13 @@ bool Scheduler::pick_next() auto exit_status = Process::reap(process); dbgprintf("reaped unparented process %s(%u), exit status: %u\n", name.characters(), pid, exit_status); } + return IterationDecision::Continue; } - return true; + if (process.m_alarm_deadline && g_uptime > process.m_alarm_deadline) { + process.m_alarm_deadline = 0; + process.send_signal(SIGALRM, nullptr); + } + return IterationDecision::Continue; }); // Dispatch any pending signals.