68 lines
1.8 KiB
Rust
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()
|
|
}
|
|
}
|