liboj_cgroups/subsystem/
cpu.rs

1use std::fs;
2use std::io;
3use std::path::Path;
4use std::time::Duration;
5
6use super::Controller;
7use crate::{
8    attr_file::{AttrFile, ReadAttr, StatMap, WriteAttr},
9    hierarchy::HierarchyNode,
10};
11
12pub trait CpuController: Controller {
13    fn shares(&self) -> Box<dyn '_ + AttrFile<usize>>;
14    fn stat(&self) -> Box<dyn '_ + ReadAttr<Stat>>;
15    fn cfs_period_us(&self) -> Box<dyn '_ + AttrFile<Duration>>;
16    fn cfs_quota_us(&self) -> Box<dyn '_ + AttrFile<Duration>>;
17}
18
19impl CpuController for HierarchyNode {
20    fn shares(&self) -> Box<dyn '_ + AttrFile<usize>> {
21        unimplemented!()
22    }
23
24    fn stat(&self) -> Box<dyn '_ + ReadAttr<Stat>> {
25        let file = StatFile(self.as_path().join("cpu.cfs_period_us"));
26        Box::new(file)
27    }
28
29    fn cfs_period_us(&self) -> Box<dyn '_ + AttrFile<Duration>> {
30        let file = CpuTimeFile(self.as_path().join("cpu.cfs_period_us"));
31        Box::new(file)
32    }
33
34    fn cfs_quota_us(&self) -> Box<dyn '_ + AttrFile<Duration>> {
35        let file = CpuTimeFile(self.as_path().join("cpu.cfs_quota_us"));
36        Box::new(file)
37    }
38}
39
40struct CpuTimeFile<P: AsRef<Path>>(P);
41
42impl<P: AsRef<Path>> ReadAttr<Duration> for CpuTimeFile<P> {
43    fn read(&self) -> io::Result<Duration> {
44        match fs::read_to_string(&self.0)?.trim().parse() {
45            Ok(us) => Ok(Duration::from_micros(us)),
46            Err(_) => Err(io::Error::new(
47                io::ErrorKind::InvalidData,
48                format!("failed to parse time from {}", self.0.as_ref().display()),
49            )),
50        }
51    }
52}
53
54impl<P: AsRef<Path>> WriteAttr<Duration> for CpuTimeFile<P> {
55    fn write(&self, attr: &Duration) -> io::Result<()> {
56        fs::write(&self.0, attr.as_micros().to_string())
57    }
58}
59
60struct StatFile<P: AsRef<Path>>(P);
61
62impl<P: AsRef<Path>> ReadAttr<Stat> for StatFile<P> {
63    fn read(&self) -> io::Result<Stat> {
64        let s = fs::read_to_string(&self.0)?;
65        let stat_map = StatMap::from(s.as_str());
66        let res = stat_attr!(stat_map, Stat, [nr_periods, nr_throttled, throttled_time]);
67        Ok(res)
68    }
69}
70
71pub struct Stat {
72    pub nr_periods: u64,
73    pub nr_throttled: u64,
74    pub throttled_time: u64,
75}