34360e1e4f
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
57 lines
1.9 KiB
Diff
57 lines
1.9 KiB
Diff
diff --git a/src/context/mod.rs b/src/context/mod.rs
|
|
--- a/src/context/mod.rs
|
|
+++ b/src/context/mod.rs
|
|
@@ -10,9 +10,9 @@ use core::{num::NonZeroUsize, ops::Deref};
|
|
|
|
use crate::{
|
|
context::memory::AddrSpaceWrapper,
|
|
- cpu_set::LogicalCpuSet,
|
|
+ cpu_set::{LogicalCpuId, LogicalCpuSet},
|
|
memory::{RmmA, RmmArch, TableKind},
|
|
- percpu::PercpuBlock,
|
|
+ percpu::{get_percpu_block, PercpuBlock},
|
|
sync::{
|
|
ArcRwLockWriteGuard, CleanLockToken, LockToken, Mutex, MutexGuard, RwLock, RwLockReadGuard,
|
|
RwLockWriteGuard, L0, L1, L2, L4,
|
|
@@ -118,6 +118,30 @@ pub fn run_contexts(token: LockToken<'_, L0>) -> MutexGuard<'_, L1, RunContextDa
|
|
RUN_CONTEXTS.lock(token)
|
|
}
|
|
|
|
+fn least_loaded_cpu() -> LogicalCpuId {
|
|
+ let current_cpu = crate::cpu_id();
|
|
+ let mut best_cpu = current_cpu;
|
|
+ let mut best_depth = usize::MAX;
|
|
+
|
|
+ for raw_id in 0..crate::cpu_count() {
|
|
+ let cpu_id = LogicalCpuId::new(raw_id);
|
|
+ let Some(percpu) = get_percpu_block(cpu_id) else {
|
|
+ continue;
|
|
+ };
|
|
+
|
|
+ percpu.sched.take_lock();
|
|
+ let depth = unsafe { percpu.sched.queues().iter().map(|queue| queue.len()).sum() };
|
|
+ percpu.sched.release_lock();
|
|
+
|
|
+ if depth < best_depth {
|
|
+ best_depth = depth;
|
|
+ best_cpu = cpu_id;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ best_cpu
|
|
+}
|
|
+
|
|
pub fn init(token: &mut CleanLockToken) {
|
|
let owner = None; // kmain not owned by any fd
|
|
let mut context = Context::new(owner).expect("failed to create kmain context");
|
|
@@ -238,6 +262,9 @@ pub fn spawn(
|
|
|
|
context.kstack = Some(stack);
|
|
context.userspace = userspace_allowed;
|
|
+ let target_cpu = least_loaded_cpu();
|
|
+ context.sched_affinity = LogicalCpuSet::empty();
|
|
+ context.sched_affinity.atomic_set(target_cpu);
|
|
|
|
let context_lock = Arc::new(ContextLock::new(context));
|
|
let context_ref = ContextRef(Arc::clone(&context_lock));
|