diff --git a/src/context/context.rs b/src/context/context.rs index 4f795841c0..4ce5b223e1 100644 --- a/src/context/context.rs +++ b/src/context/context.rs @@ -493,6 +493,52 @@ impl Context { core::mem::replace(&mut self.addr_space, addr_space) } + /// Set the scheduling policy and RT priority for this context. + /// + /// `policy` selects SCHED_FIFO / SCHED_RR / SCHED_OTHER. `rt_priority` is + /// POSIX 0..99 for FIFO/RR (clamped); ignored for SCHED_OTHER (which uses + /// `sched_static_prio` set via [`Self::set_sched_other_prio`]). + /// + /// The mapping from POSIX `rt_priority` to the kernel's + /// `SCHED_PRIORITY_LEVELS` (0..=39, higher = lower priority) is the + /// standard inverse weighting: rt_priority 99 maps to level 0 (highest + /// priority), rt_priority 0 maps to level 39 (lowest). The actual + /// kernel priority level is computed by [`rt_priority_to_kernel_prio`]. + /// + /// `sched_rr_ticks_consumed` is reset to 0 so that a fresh RR quantum + /// begins on the next scheduler pass. + pub fn set_sched_policy(&mut self, policy: SchedPolicy, rt_priority: u8) { + self.sched_policy = policy; + self.sched_rt_priority = match policy { + SchedPolicy::Other => 0, + SchedPolicy::Fifo | SchedPolicy::RoundRobin => rt_priority.min(99), + }; + self.sched_rr_ticks_consumed = 0; + if matches!(policy, SchedPolicy::Fifo | SchedPolicy::RoundRobin) { + self.sched_static_prio = rt_priority_to_kernel_prio(self.sched_rt_priority); + self.prio = self.sched_static_prio; + } + } + + /// Set the SCHED_OTHER priority (nice level) for this context. + /// + /// `prio` is the kernel priority level 0..=39, where 39 is the lowest + /// nice value (highest CPU weight) and 0 is the highest nice value + /// (lowest CPU weight, equivalent to nice +19). The clamping and + /// conversion from POSIX nice is the responsibility of the caller + /// (see `kernel_prio_to_nice` / `nice_to_kernel_prio` in + /// `scheme/proc.rs`). + /// + /// SCHED_OTHER contexts accumulate vruntime faster at higher kernel + /// priority (lower nice) — see the DWRR weight table in + /// `context/switch.rs:30-34`. Setting this does NOT change the + /// scheduling class; use [`Self::set_sched_policy`] for that. + pub fn set_sched_other_prio(&mut self, prio: usize) { + let clamped = clamp_sched_other_prio(prio); + self.sched_static_prio = clamped; + self.prio = clamped; + } + fn can_access_regs(&self) -> bool { self.userspace }