From 083c5f8b89ff7322770e53c640202b630864ba0d Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 6 Nov 2019 16:26:51 +0100 Subject: [PATCH] Kernel: Rework Process::Priority into ThreadPriority Scheduling priority is now set at the thread level instead of at the process level. This is a step towards allowing processes to set different priorities for threads. There's no userspace API for that yet, since only the main thread's priority is affected by sched_setparam(). --- Kernel/FileSystem/ProcFS.cpp | 2 +- Kernel/Process.cpp | 23 +++-------------------- Kernel/Process.h | 15 +-------------- Kernel/Scheduler.cpp | 16 ++++++++-------- Kernel/Thread.cpp | 17 +++++++++++++++++ Kernel/Thread.h | 13 +++++++++++++ Kernel/init.cpp | 6 +++--- 7 files changed, 46 insertions(+), 46 deletions(-) diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index 92f3d5fd90d..fc08632be75 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/Kernel/FileSystem/ProcFS.cpp @@ -688,7 +688,7 @@ Optional procfs$all(InodeIdentifier) process_object.add("amount_resident", (u32)process.amount_resident()); process_object.add("amount_shared", (u32)process.amount_shared()); process_object.add("ticks", process.main_thread().ticks()); - process_object.add("priority", to_string(process.priority())); + process_object.add("priority", to_string(process.main_thread().priority())); process_object.add("syscall_count", process.syscall_count()); process_object.add("inode_faults", process.inode_faults()); process_object.add("zero_faults", process.zero_faults()); diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index f964e910311..e41b40cf040 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -2555,10 +2555,10 @@ int Process::sys$sched_setparam(pid_t pid, const struct sched_param* param) if (!is_superuser() && m_euid != peer->m_uid && m_uid != peer->m_uid) return -EPERM; - if (param->sched_priority < Process::FirstPriority || param->sched_priority > Process::LastPriority) + if (param->sched_priority < (int)ThreadPriority::First || param->sched_priority > (int)ThreadPriority::Last) return -EINVAL; - peer->set_priority(Priority(param->sched_priority)); + peer->main_thread().set_priority((ThreadPriority)param->sched_priority); return 0; } @@ -2578,7 +2578,7 @@ int Process::sys$sched_getparam(pid_t pid, struct sched_param* param) if (!is_superuser() && m_euid != peer->m_uid && m_uid != peer->m_uid) return -EPERM; - param->sched_priority = peer->priority(); + param->sched_priority = (int)peer->main_thread().priority(); return 0; } @@ -2755,23 +2755,6 @@ int Process::sys$get_shared_buffer_size(int shared_buffer_id) return shared_buffer.size(); } -const char* to_string(Process::Priority priority) -{ - switch (priority) { - case Process::IdlePriority: - return "Idle"; - case Process::LowPriority: - return "Low"; - case Process::NormalPriority: - return "Normal"; - case Process::HighPriority: - return "High"; - } - kprintf("to_string(Process::Priority): Invalid priority: %u\n", priority); - ASSERT_NOT_REACHED(); - return nullptr; -} - void Process::terminate_due_to_signal(u8 signal) { ASSERT_INTERRUPTS_DISABLED(); diff --git a/Kernel/Process.h b/Kernel/Process.h index 9513a912371..63470bce861 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -44,15 +44,6 @@ public: static Vector all_pids(); static Vector all_processes(); - enum Priority : u8 { - IdlePriority, - FirstPriority = IdlePriority, - LowPriority, - NormalPriority, - HighPriority, - LastPriority = HighPriority, - }; - enum RingLevel : u8 { Ring0 = 0, Ring3 = 3, @@ -75,9 +66,6 @@ public: static Process* from_pid(pid_t); - void set_priority(Priority p) { m_priority = p; } - Priority priority() const { return m_priority; } - const String& name() const { return m_name; } pid_t pid() const { return m_pid; } pid_t sid() const { return m_sid; } @@ -351,7 +339,6 @@ private: Vector m_fds; RingLevel m_ring { Ring0 }; - Priority m_priority { NormalPriority }; u8 m_termination_status { 0 }; u8 m_termination_signal { 0 }; @@ -429,7 +416,7 @@ private: Process& m_process; }; -extern const char* to_string(Process::Priority); +const char* to_string(ThreadPriority); extern InlineLinkedList* g_processes; diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp index 795a2ef183d..812ae437e19 100644 --- a/Kernel/Scheduler.cpp +++ b/Kernel/Scheduler.cpp @@ -27,17 +27,17 @@ void Scheduler::update_state_for_thread(Thread& thread) //#define SCHEDULER_DEBUG //#define SCHEDULER_RUNNABLE_DEBUG -static u32 time_slice_for(Process::Priority priority) +static u32 time_slice_for(ThreadPriority priority) { // One time slice unit == 1ms switch (priority) { - case Process::HighPriority: + case ThreadPriority::High: return 50; - case Process::NormalPriority: + case ThreadPriority::Normal: return 15; - case Process::LowPriority: + case ThreadPriority::Low: return 5; - case Process::IdlePriority: + case ThreadPriority::Idle: return 1; } ASSERT_NOT_REACHED(); @@ -387,7 +387,7 @@ bool Scheduler::donate_to(Thread* beneficiary, const char* reason) if (!beneficiary || beneficiary->state() != Thread::Runnable || ticks_left <= 1) return yield(); - unsigned ticks_to_donate = min(ticks_left - 1, time_slice_for(beneficiary->process().priority())); + unsigned ticks_to_donate = min(ticks_left - 1, time_slice_for(beneficiary->priority())); #ifdef SCHEDULER_DEBUG dbgprintf("%s(%u:%u) donating %u ticks to %s(%u:%u), reason=%s\n", current->process().name().characters(), current->pid(), current->tid(), ticks_to_donate, beneficiary->process().name().characters(), beneficiary->pid(), beneficiary->tid(), reason); #endif @@ -429,7 +429,7 @@ void Scheduler::switch_now() bool Scheduler::context_switch(Thread& thread) { - thread.set_ticks_left(time_slice_for(thread.process().priority())); + thread.set_ticks_left(time_slice_for(thread.priority())); thread.did_schedule(); if (current == &thread) @@ -521,7 +521,7 @@ void Scheduler::initialize() initialize_redirection(); s_colonel_process = Process::create_kernel_process("colonel", nullptr); // Make sure the colonel uses a smallish time slice. - s_colonel_process->set_priority(Process::IdlePriority); + s_colonel_process->main_thread().set_priority(ThreadPriority::Idle); load_task_register(s_redirection.selector); } diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index 410eeca2e05..29d0ab25edd 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -670,3 +670,20 @@ const LogStream& operator<<(const LogStream& stream, const Thread& value) { return stream << value.process().name() << "(" << value.pid() << ":" << value.tid() << ")"; } + +const char* to_string(ThreadPriority priority) +{ + switch (priority) { + case ThreadPriority::Idle: + return "Idle"; + case ThreadPriority::Low: + return "Low"; + case ThreadPriority::Normal: + return "Normal"; + case ThreadPriority::High: + return "High"; + } + dbg() << "to_string(ThreadPriority): Invalid priority: " << (u32)priority; + ASSERT_NOT_REACHED(); + return nullptr; +} diff --git a/Kernel/Thread.h b/Kernel/Thread.h index baf18bb8b69..da7d2bc248b 100644 --- a/Kernel/Thread.h +++ b/Kernel/Thread.h @@ -34,6 +34,15 @@ struct ThreadSpecificData { ThreadSpecificData* self; }; +enum class ThreadPriority : u8 { + Idle, + Low, + Normal, + High, + First = Idle, + Last = High, +}; + class Thread { friend class Process; friend class Scheduler; @@ -51,6 +60,9 @@ public: int tid() const { return m_tid; } int pid() const; + void set_priority(ThreadPriority p) { m_priority = p; } + ThreadPriority priority() const { return m_priority; } + Process& process() { return m_process; } const Process& process() const { return m_process; } @@ -341,6 +353,7 @@ private: Blocker* m_blocker { nullptr }; FPUState* m_fpu_state { nullptr }; State m_state { Invalid }; + ThreadPriority m_priority { ThreadPriority::Normal }; bool m_has_used_fpu { false }; bool m_dump_backtrace_on_finalization { false }; diff --git a/Kernel/init.cpp b/Kernel/init.cpp index aa1a24741f9..77f60f1c106 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -170,7 +170,7 @@ VFS* vfs; kprintf("init_stage2: error spawning Shell: %d\n", error); hang(); } - shell_process->set_priority(Process::HighPriority); + shell_process->main_thread().set_priority(ThreadPriority::High); } else { tty0->set_graphical(true); auto* system_server_process = Process::create_user_process("/bin/SystemServer", (uid_t)0, (gid_t)0, (pid_t)0, error, {}, {}, tty0); @@ -178,7 +178,7 @@ VFS* vfs; kprintf("init_stage2: error spawning SystemServer: %d\n", error); hang(); } - system_server_process->set_priority(Process::HighPriority); + system_server_process->main_thread().set_priority(ThreadPriority::High); } Process::create_kernel_process("NetworkTask", NetworkTask_main); @@ -313,7 +313,7 @@ extern "C" [[noreturn]] void init() }); Process::create_kernel_process("Finalizer", [] { g_finalizer = current; - current->process().set_priority(Process::LowPriority); + current->set_priority(ThreadPriority::Low); for (;;) { Thread::finalize_dying_threads(); (void)current->block(Thread::SemiPermanentBlocker::Reason::Lurking);