Red Bear OS kernel baseline
From release 0.1.0 pre-patched archive. This includes all Red Bear modifications previously maintained as patches in local/patches/kernel/.
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
use alloc::collections::VecDeque;
|
||||
|
||||
use crate::{
|
||||
event,
|
||||
scheme::SchemeId,
|
||||
sync::{CleanLockToken, LockToken, Mutex, MutexGuard, L0, L1},
|
||||
syscall::{
|
||||
data::TimeSpec,
|
||||
flag::{CLOCK_MONOTONIC, CLOCK_REALTIME, EVENT_READ},
|
||||
},
|
||||
time,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Timeout {
|
||||
pub scheme_id: SchemeId,
|
||||
pub event_id: usize,
|
||||
pub clock: usize,
|
||||
pub time: u128,
|
||||
}
|
||||
|
||||
type Registry = VecDeque<Timeout>;
|
||||
|
||||
static REGISTRY: Mutex<L1, Registry> = Mutex::new(Registry::new());
|
||||
|
||||
/// Get the global timeouts list
|
||||
fn registry(token: LockToken<'_, L0>) -> MutexGuard<'_, L1, Registry> {
|
||||
REGISTRY.lock(token)
|
||||
}
|
||||
|
||||
pub fn register(
|
||||
scheme_id: SchemeId,
|
||||
event_id: usize,
|
||||
clock: usize,
|
||||
time: TimeSpec,
|
||||
token: &mut CleanLockToken,
|
||||
) {
|
||||
let mut registry = registry(token.token());
|
||||
registry.push_back(Timeout {
|
||||
scheme_id,
|
||||
event_id,
|
||||
clock,
|
||||
time: (time.tv_sec as u128 * time::NANOS_PER_SEC) + (time.tv_nsec as u128),
|
||||
});
|
||||
}
|
||||
|
||||
pub fn trigger(token: &mut CleanLockToken) {
|
||||
let mono = time::monotonic(token);
|
||||
let real = time::realtime(token);
|
||||
|
||||
let mut i = 0;
|
||||
loop {
|
||||
let mut registry = registry(token.token());
|
||||
let timeout = if i < registry.len() {
|
||||
let trigger = match registry[i].clock {
|
||||
CLOCK_MONOTONIC => {
|
||||
let time = registry[i].time;
|
||||
mono >= time
|
||||
}
|
||||
CLOCK_REALTIME => {
|
||||
let time = registry[i].time;
|
||||
real >= time
|
||||
}
|
||||
clock => {
|
||||
println!("timeout::trigger: unknown clock {}", clock);
|
||||
true
|
||||
}
|
||||
};
|
||||
|
||||
if trigger {
|
||||
registry.remove(i).unwrap()
|
||||
} else {
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
};
|
||||
drop(registry);
|
||||
event::trigger(timeout.scheme_id, timeout.event_id, EVENT_READ, token);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user