Files
k-os/crates/domain/src/timer.rs

68 lines
1.8 KiB
Rust

//! Events the kernel reports by signalling a notification: a process's
//! death, a deadline passing. One timer per process.
use types::{badge::Badge, generation::Generation, id::NotificationId, id::ProcessId, time::Ticks};
use crate::process::MAX_PROCESSES;
#[cfg(test)]
#[path = "timer_tests.rs"]
mod tests;
/// A notification as a capability named it; once the notification is
/// destroyed (its generation moves on) the target is dead.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Target {
pub notification: NotificationId,
pub generation: Generation,
pub badge: Badge,
}
pub struct Timers {
deadlines: [Option<(Ticks, Target)>; MAX_PROCESSES],
}
impl Timers {
pub const fn new() -> Self {
Self {
deadlines: [None; MAX_PROCESSES],
}
}
/// Replaces `owner`'s timer.
pub fn set(&mut self, owner: ProcessId, deadline: Ticks, target: Target) -> bool {
match self.deadlines.get_mut(owner.raw() as usize) {
Some(slot) => {
*slot = Some((deadline, target));
true
}
None => false,
}
}
pub fn clear(&mut self, owner: ProcessId) {
if let Some(slot) = self.deadlines.get_mut(owner.raw() as usize) {
*slot = None;
}
}
/// Removes and returns one timer whose deadline is at or before `now`.
pub fn take_expired(&mut self, now: Ticks) -> Option<Target> {
let slot = self
.deadlines
.iter_mut()
.find(|s| s.is_some_and(|(d, _)| d <= now))?;
slot.take().map(|(_, t)| t)
}
pub fn earliest(&self) -> Option<Ticks> {
self.deadlines.iter().flatten().map(|(d, _)| *d).min()
}
}
impl Default for Timers {
fn default() -> Self {
Self::new()
}
}