1mod ffi;
2
3use core::time::Duration;
4use libc::{c_longlong, c_ulong};
5use nix::unistd::Uid;
6use realtime_core::*;
7
8pub struct Xenomai {
9 start_time: c_longlong,
10}
11
12impl Xenomai {
13 pub fn new(prio: i32) -> Result<Self> {
14 if !Uid::effective().is_root() {
16 return Err(ErrorKind::NotRoot);
17 }
18 unsafe { ffi::init() };
19 match unsafe { ffi::shadow(prio, 1) } {
20 0 => {}
21 x => return Err(ErrorKind::Unknown(x as isize)),
22 }
23
24 Ok(Self { start_time: 0 })
25 }
26
27 pub fn get_time_ns() -> u64 {
28 unsafe { ffi::read() as u64 }
29 }
30}
31impl RealTime for Xenomai {
32 fn start(&mut self, period: Duration) -> Result<()> {
33 let period = period.as_nanos() as c_longlong;
34 let start_time = unsafe { ffi::read() } + period;
35 match unsafe { ffi::set_periodic(start_time, period) } {
36 0 => {
37 self.start_time = start_time;
38 log::info!(
39 "Xenomai start: period={}, start_time={}",
40 period,
41 start_time
42 );
43 Ok(())
44 }
45 x => Err(ErrorKind::Unknown(x as isize)),
46 }
47 }
48 fn stop(&mut self) -> Result<()> {
49 if self.start_time == 0 {
50 return Ok(());
51 }
52 match unsafe { ffi::set_periodic(0, 0) } {
53 0 => {
54 self.start_time = 0;
55 Ok(())
56 }
57 x => Err(ErrorKind::Unknown(x as isize)),
58 }
59 }
60 fn wait_period(&mut self) -> Result<()> {
61 if self.start_time == 0 {
62 return Err(ErrorKind::NotStart);
63 }
64 let mut overrun: c_ulong = 0;
65 match unsafe { ffi::wait_period(&mut overrun as *mut _) } {
66 0 => Ok(()),
67 x => Err(ErrorKind::Unknown(x as isize)),
68 }
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn tolerance() {
78 let mut xenomai = Xenomai::new(90).unwrap();
79 xenomai.start(Duration::from_millis(1)).unwrap();
80 xenomai.wait_period().unwrap();
81 let mut last_time = clock_source::now();
82 for _ in 0..1_000 {
83 xenomai.wait_period().unwrap();
84 let now = clock_source::now();
85 if now - last_time > 1_200_000 {
86 println!("{}", now - last_time - 1_000_000);
87 }
88 assert!(now - last_time < 1_200_000);
89 last_time = now;
90 }
91 }
92}