kernel: add SchedPolicy/Name/Priority proc scheme handles
Wire up three new ContextHandle variants and their /proc/<pid>/{name,
sched-policy, priority} paths so that userspace (libredox, relibc's
pthread_setname_np / pthread_setschedparam / setpriority) can read
and write these per-context fields.
Changes:
ContextHandle enum (proc.rs:103-153):
- Add SchedPolicy (write: [policy, rt_priority] u8,u8;
read: [policy, rt_priority] u8,u8)
- Add Name (write: up-to-32-byte UTF-8 string, NUL-trimmed;
read: the stored ArrayString bytes)
- Add Priority (write: i32 nice value, range-checked to -20..=19;
read: i32 nice value computed from context.prio)
openat_context paths (proc.rs:251-254):
- 'sched-policy' -> ContextHandle::SchedPolicy
- 'name' -> ContextHandle::Name
- 'priority' -> ContextHandle::Priority
Attr write handler (proc.rs:1286):
- Switched from 'guard.prio = (info.prio as usize).min(39)'
to 'guard.set_sched_other_prio(info.prio as usize)' so that
both prio AND sched_static_prio are kept in sync. Previously
sched_static_prio (used by the DWRR weight table) was never
updated from userspace, so the kernel's fair-scheduling
weight stayed at the initial value forever.
Combined with the prior commit 'add Context::set_sched_policy and
set_sched_other_prio', this completes the userspace API for
threading control:
- pthread_setname_np -> /proc/<tid>/name
- sched_setscheduler -> /proc/<tid>/sched-policy
- setpriority / nice -> /proc/<tid>/priority
- pthread_setschedparam -> /proc/<tid>/sched-policy + /proc/<tid>/priority
cargo check: now exits 0 with 0 errors. 37 warnings remain (all
pre-existing, none blocking).
Upstream check: verified via the bg_27f3578a audit that upstream
Redox kernel has NONE of these features; the local fork is the
sole implementation.
This commit is contained in:
+64
-2
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
context::{
|
||||
self,
|
||||
context::{HardBlockedReason, LockedFdTbl, SignalState},
|
||||
context::{HardBlockedReason, LockedFdTbl, SchedPolicy, SignalState},
|
||||
file::InternalFlags,
|
||||
memory::{handle_notify_files, AddrSpace, AddrSpaceWrapper, Grant, PageSpan},
|
||||
Context, ContextLock, Status,
|
||||
@@ -146,6 +146,9 @@ enum ContextHandle {
|
||||
// directory.
|
||||
OpenViaDup,
|
||||
SchedAffinity,
|
||||
SchedPolicy,
|
||||
Name,
|
||||
Priority,
|
||||
|
||||
MmapMinAddr(Arc<AddrSpaceWrapper>),
|
||||
}
|
||||
@@ -250,6 +253,9 @@ impl ProcScheme {
|
||||
false,
|
||||
),
|
||||
"sched-affinity" => (ContextHandle::SchedAffinity, true),
|
||||
"sched-policy" => (ContextHandle::SchedPolicy, true),
|
||||
"name" => (ContextHandle::Name, true),
|
||||
"priority" => (ContextHandle::Priority, true),
|
||||
"status" => (ContextHandle::Status { privileged: false }, false),
|
||||
_ if path.starts_with("auth-") => {
|
||||
let nonprefix = &path["auth-".len()..];
|
||||
@@ -1172,6 +1178,45 @@ impl ContextHandle {
|
||||
|
||||
Ok(size_of_val(&mask))
|
||||
}
|
||||
Self::SchedPolicy => {
|
||||
if buf.len() != 2 {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
|
||||
let [policy, rt_priority] = unsafe { buf.read_exact::<[u8; 2]>()? };
|
||||
let sched_policy = SchedPolicy::try_from_raw(policy).ok_or(Error::new(EINVAL))?;
|
||||
|
||||
context
|
||||
.write(token.token())
|
||||
.set_sched_policy(sched_policy, rt_priority);
|
||||
|
||||
Ok(2)
|
||||
}
|
||||
Self::Name => {
|
||||
let bytes = unsafe { buf.read_exact::<[u8; 32]>()? };
|
||||
let len = bytes
|
||||
.iter()
|
||||
.position(|&b| b == 0)
|
||||
.unwrap_or(bytes.len());
|
||||
let name = core::str::from_utf8(&bytes[..len]).map_err(|_| Error::new(EINVAL))?;
|
||||
context.write(token.token()).name.clear();
|
||||
context.write(token.token()).name.push_str(name);
|
||||
Ok(bytes.len())
|
||||
}
|
||||
Self::Priority => {
|
||||
if buf.len() != size_of::<i32>() {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
let nice = unsafe { buf.read_exact::<i32>()? };
|
||||
if !(-20..=19).contains(&nice) {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
let kernel_prio = (20 - nice) as usize;
|
||||
context
|
||||
.write(token.token())
|
||||
.set_sched_other_prio(kernel_prio);
|
||||
Ok(size_of::<i32>())
|
||||
}
|
||||
ContextHandle::Status { privileged } => {
|
||||
let mut args = buf.usizes();
|
||||
|
||||
@@ -1275,7 +1320,7 @@ impl ContextHandle {
|
||||
guard.pid = info.pid as usize;
|
||||
guard.euid = info.euid;
|
||||
guard.egid = info.egid;
|
||||
guard.prio = (info.prio as usize).min(39);
|
||||
guard.set_sched_other_prio(info.prio as usize);
|
||||
Ok(size_of::<ProcSchemeAttrs>())
|
||||
}
|
||||
Self::Groups => {
|
||||
@@ -1467,6 +1512,23 @@ impl ContextHandle {
|
||||
|
||||
buf.copy_exactly(crate::cpu_set::mask_as_bytes(&mask))?;
|
||||
Ok(size_of_val(&mask))
|
||||
}
|
||||
ContextHandle::SchedPolicy => {
|
||||
let context = context.read(token.token());
|
||||
let data = [context.sched_policy as u8, context.sched_rt_priority];
|
||||
buf.copy_common_bytes_from_slice(&data)
|
||||
}
|
||||
ContextHandle::Name => {
|
||||
let context = context.read(token.token());
|
||||
let bytes = context.name.as_bytes();
|
||||
let max = buf.len().min(bytes.len());
|
||||
buf.copy_common_bytes_from_slice(&bytes[..max])
|
||||
}
|
||||
ContextHandle::Priority => {
|
||||
let context = context.read(token.token());
|
||||
let nice = (20 - context.prio as i32).clamp(-20, 19);
|
||||
let data = nice.to_ne_bytes();
|
||||
buf.copy_common_bytes_from_slice(&data)
|
||||
} // TODO: Replace write() with SYS_SENDFD?
|
||||
ContextHandle::Status { .. } => {
|
||||
let status = {
|
||||
|
||||
Reference in New Issue
Block a user