feat: P0-P6 kernel scheduler + relibc threading comprehensive implementation
P0-P2: Barrier SMP, sigmask/pthread_kill races, robust mutexes, RT scheduling, POSIX sched API P3: PerCpuSched struct, per-CPU wiring, work stealing, load balancing, initial placement P4: 64-shard futex table, REQUEUE, PI futexes (LOCK_PI/UNLOCK_PI/TRYLOCK_PI), robust futexes, vruntime tracking, min-vruntime SCHED_OTHER selection P5: setpriority/getpriority, pthread_setaffinity_np, pthread_setname_np, pthread_setschedparam (Redox) P6: Cache-affine scheduling (last_cpu + vruntime bonus), NUMA topology kernel hints + numad userspace daemon Stability fixes: make_consistent stores 0 (dead TID fix), cond.rs error propagation, SPIN_COUNT adaptive spinning, Sys::open &str fix, PI futex CAS race, proc.rs lock ordering, barrier destroy Patches: 33 kernel + 58 relibc patches, all tracked in recipes Docs: KERNEL-SCHEDULER-MULTITHREAD-IMPROVEMENT-PLAN.md updated, SCHEDULER-REVIEW-FINAL.md created Architecture: NUMA topology parsing stays userspace (numad daemon), kernel stores lightweight NumaTopology hints
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs
|
||||
--- a/src/scheme/proc.rs
|
||||
+++ b/src/scheme/proc.rs
|
||||
@@ -145,8 +145,9 @@ enum ContextHandle {
|
||||
// TODO: Remove this once openat is implemented, or allow openat-via-dup via e.g. the top-level
|
||||
// directory.
|
||||
OpenViaDup,
|
||||
+ Priority,
|
||||
SchedAffinity,
|
||||
SchedPolicy,
|
||||
Name,
|
||||
|
||||
MmapMinAddr(Arc<AddrSpaceWrapper>),
|
||||
@@ -160,6 +161,17 @@ pub struct ProcScheme;
|
||||
static NEXT_ID: AtomicUsize = AtomicUsize::new(1);
|
||||
static HANDLES: RwLock<L1, HashMap<usize, Handle>> =
|
||||
RwLock::new(HashMap::with_hasher(DefaultHashBuilder::new()));
|
||||
+
|
||||
+const NICE_MIN: i32 = -20;
|
||||
+const NICE_MAX: i32 = 19;
|
||||
+
|
||||
+fn nice_to_kernel_prio(nice: i32) -> usize {
|
||||
+ (nice.saturating_add(20)).clamp(0, 39) as usize
|
||||
+}
|
||||
+
|
||||
+fn kernel_prio_to_nice(prio: usize) -> i32 {
|
||||
+ (prio.min(39) as i32) - 20
|
||||
+}
|
||||
|
||||
#[cfg(feature = "debugger")]
|
||||
#[allow(dead_code)]
|
||||
pub fn foreach_addrsp(
|
||||
@@ -253,6 +265,7 @@ impl ProcScheme {
|
||||
"sighandler" => (ContextHandle::Sighandler, false),
|
||||
"start" => (ContextHandle::Start, false),
|
||||
"open_via_dup" => (ContextHandle::OpenViaDup, false),
|
||||
+ "priority" => (ContextHandle::Priority, false),
|
||||
"mmap-min-addr" => (
|
||||
ContextHandle::MmapMinAddr(Arc::clone(
|
||||
context
|
||||
@@ -1191,6 +1204,17 @@ impl ContextHandle {
|
||||
|
||||
Ok(size_of_val(&mask))
|
||||
}
|
||||
+ Self::Priority => {
|
||||
+ let nice = unsafe { buf.read_exact::<i32>()? };
|
||||
+ if !(NICE_MIN..=NICE_MAX).contains(&nice) {
|
||||
+ return Err(Error::new(EINVAL));
|
||||
+ }
|
||||
+
|
||||
+ context
|
||||
+ .write(token.token())
|
||||
+ .set_sched_other_prio(nice_to_kernel_prio(nice));
|
||||
+
|
||||
+ Ok(size_of::<i32>())
|
||||
+ }
|
||||
Self::SchedPolicy => {
|
||||
if buf.len() != 2 {
|
||||
return Err(Error::new(EINVAL));
|
||||
@@ -1522,6 +1546,10 @@ impl ContextHandle {
|
||||
|
||||
buf.copy_exactly(crate::cpu_set::mask_as_bytes(&mask))?;
|
||||
Ok(size_of_val(&mask))
|
||||
+ }
|
||||
+ ContextHandle::Priority => {
|
||||
+ let nice = kernel_prio_to_nice(context.read(token.token()).prio);
|
||||
+ buf.copy_common_bytes_from_slice(&nice.to_ne_bytes())
|
||||
}
|
||||
ContextHandle::SchedPolicy => {
|
||||
let context = context.read(token.token());
|
||||
Reference in New Issue
Block a user