Files
RedBear-OS/drivers/common/src/timeout.rs
T

57 lines
1.7 KiB
Rust

use std::time::{Duration, Instant};
/// Represents an amount of time for a driver to give up to the OS scheduler.
pub struct Timeout {
instant: Instant,
duration: Duration,
}
impl Timeout {
/// Create a new `Timeout` from a `Duration`.
#[inline]
pub fn new(duration: Duration) -> Self {
Self {
instant: Instant::now(),
duration,
}
}
/// Create a new `Timeout` by specifying the amount of microseconds.
#[inline]
pub fn from_micros(micros: u64) -> Self {
Self::new(Duration::from_micros(micros))
}
/// Create a new `Timeout` by specifying the amount of milliseconds.
#[inline]
pub fn from_millis(millis: u64) -> Self {
Self::new(Duration::from_millis(millis))
}
/// Create a new `Timeout` by specifying the amount of seconds.
#[inline]
pub fn from_secs(secs: u64) -> Self {
Self::new(Duration::from_secs(secs))
}
/// Execute the `Timeout`.
///
/// # Errors
///
/// Returns an `Err` if the duration of the `Timeout` has already elapsed
/// between creating the `Timeout` and calling this function.
#[inline]
pub fn run(&self) -> Result<(), ()> {
if self.instant.elapsed() < self.duration {
// Sleeps in Redox are only evaluated on PIT ticks (a few ms), which is not
// short enough for a reasonably responsive timeout. However, the clock is
// highly accurate. So, we yield instead of sleep to reduce latency.
//TODO: allow timeout that spins instead of yields?
std::thread::yield_now();
Ok(())
} else {
Err(())
}
}
}