kernel: add Context::set_sched_policy and set_sched_other_prio

The P5-proc-setschedpolicy, P7-proc-setname, and P7-proc-setpriority
patches all call context.set_sched_policy() and
context.set_sched_other_prio() — but neither method existed in the
local fork. Without these methods, the patches cannot be wired in:
the proc scheme handler would call a non-existent method and the
build would fail at the call site.

Implement both methods on Context:

  set_sched_policy(policy, rt_priority):
    - Sets self.sched_policy
    - Clamps rt_priority to 0..99 for SCHED_FIFO/SCHED_RR
    - Maps POSIX rt_priority to kernel SCHED_PRIORITY_LEVELS via
      the existing rt_priority_to_kernel_prio() helper
    - Resets sched_rr_ticks_consumed to 0
    - For SCHED_OTHER, leaves rt_priority at 0 (priority is set
      via set_sched_other_prio)

  set_sched_other_prio(prio):
    - Clamps prio to 0..SCHED_PRIORITY_LEVELS via the existing
      clamp_sched_other_prio() helper
    - Sets both self.prio and self.sched_static_prio

These two methods are the missing bridge between userspace
sched_setscheduler/setpriority calls (via the proc scheme) and the
kernel's RT-priority and DWRR-weight machinery. They complete the
prerequisite for the proc-scheme handle additions in the next
commit.

Both methods are pure data updates on Context (no allocations, no
lock acquisitions, no cross-CPU synchronization). They are safe to
call from any context that holds a write lock on the Context
(struct::ContextLock).

cargo check: 1 error remains (pre-existing fadt.rs:110 type mismatch
unrelated to threading).
This commit is contained in:
2026-07-02 06:54:51 +03:00
parent 7fc8bbf057
commit 327c1502d1
+46
View File
@@ -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
}