Skip to content

Commit

Permalink
Add support for /proc/uptime
Browse files Browse the repository at this point in the history
  • Loading branch information
oblique committed Oct 4, 2021
1 parent 79cc96c commit 9496843
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/lib.rs
Expand Up @@ -288,6 +288,9 @@ pub use locks::*;

pub mod keyring;

mod uptime;
pub use uptime::*;

lazy_static! {
/// The number of clock ticks per second.
///
Expand Down
75 changes: 75 additions & 0 deletions src/uptime.rs
@@ -0,0 +1,75 @@
use crate::{FileWrapper, ProcResult};

use std::io::Read;
use std::str::FromStr;
use std::time::Duration;

/// The uptime of the system, based on the `/proc/uptime` file.
#[derive(Debug, Clone)]
pub struct Uptime {
_private: (),

/// The uptime of the system (including time spent in suspend).
pub uptime: f64,

/// The sum of how much time each core has spent idle.
pub idle: f64,
}

impl Uptime {
pub fn new() -> ProcResult<Uptime> {
let file = FileWrapper::open("/proc/uptime")?;
Uptime::from_reader(file)
}

pub fn from_reader<R: Read>(mut r: R) -> ProcResult<Uptime> {
let mut buf = Vec::with_capacity(128);
r.read_to_end(&mut buf)?;

let line = String::from_utf8_lossy(&buf);
let buf = line.trim();

let mut s = buf.split(' ');
let uptime = expect!(f64::from_str(expect!(s.next())));
let idle = expect!(f64::from_str(expect!(s.next())));

Ok(Uptime {
_private: (),
uptime,
idle,
})
}

/// The uptime of the system (including time spent in suspend).
pub fn uptime_duration(&self) -> Duration {
let secs = self.uptime.trunc() as u64;
let csecs = (self.uptime.fract() * 100.0).round() as u32;
let nsecs = csecs * 10_000_000;

Duration::new(secs, nsecs)
}

/// The sum of how much time each core has spent idle.
pub fn idle_duration(&self) -> Duration {
let secs = self.idle.trunc() as u64;
let csecs = (self.idle.fract() * 100.0).round() as u32;
let nsecs = csecs * 10_000_000;

Duration::new(secs, nsecs)
}
}

#[cfg(test)]
mod tests {
use super::*;
use std::io::Cursor;

#[test]
fn test_uptime() {
let reader = Cursor::new(b"2578790.61 1999230.98\n");
let uptime = Uptime::from_reader(reader).unwrap();

assert_eq!(uptime.uptime_duration(), Duration::new(2578790, 610_000_000));
assert_eq!(uptime.idle_duration(), Duration::new(1999230, 980_000_000));
}
}

0 comments on commit 9496843

Please sign in to comment.