43 lines
1.6 KiB
Rust
43 lines
1.6 KiB
Rust
//! State published under the kernel lock for lock-free fast paths to read.
|
|
|
|
use core::sync::atomic::{AtomicUsize, Ordering};
|
|
|
|
use super::{MAX_HARTS, hart_id};
|
|
|
|
/// Per core: highest waiting priority + 1, 0 if its queue is empty.
|
|
static WAITING: [AtomicUsize; MAX_HARTS] = [const { AtomicUsize::new(0) }; MAX_HARTS];
|
|
/// Per hart: the running thread's process id + 1 and priority + 1.
|
|
static RUNNING_PID: [AtomicUsize; MAX_HARTS] = [const { AtomicUsize::new(0) }; MAX_HARTS];
|
|
static RUNNING_PRIORITY: [AtomicUsize; MAX_HARTS] = [const { AtomicUsize::new(0) }; MAX_HARTS];
|
|
|
|
pub fn publish_waiting(core: usize, highest: Option<u8>) {
|
|
if let Some(w) = WAITING.get(core) {
|
|
w.store(highest.map_or(0, |p| p as usize + 1), Ordering::Release);
|
|
}
|
|
}
|
|
|
|
pub fn publish_running(pid: Option<u16>, priority: Option<u8>) {
|
|
let me = hart_id();
|
|
if let (Some(p), Some(q)) = (RUNNING_PID.get(me), RUNNING_PRIORITY.get(me)) {
|
|
p.store(pid.map_or(0, |x| x as usize + 1), Ordering::Release);
|
|
q.store(priority.map_or(0, |x| x as usize + 1), Ordering::Release);
|
|
}
|
|
}
|
|
|
|
/// The process the thread running on this hart belongs to.
|
|
pub fn running_pid() -> Option<usize> {
|
|
let v = RUNNING_PID.get(hart_id())?.load(Ordering::Acquire);
|
|
v.checked_sub(1)
|
|
}
|
|
|
|
/// Whether a Yield by the running thread would change nothing: no thread
|
|
/// waits on this core at its priority or above.
|
|
pub fn yield_is_noop() -> bool {
|
|
let me = hart_id();
|
|
let (Some(w), Some(p)) = (WAITING.get(me), RUNNING_PRIORITY.get(me)) else {
|
|
return false;
|
|
};
|
|
let mine = p.load(Ordering::Acquire);
|
|
mine != 0 && w.load(Ordering::Acquire) < mine
|
|
}
|