1extern crate libc;
2use std::io::{Result, Error};
3use std::time::Duration;
4
5use libc::{clock_gettime, timespec};
6use libc::{pthread_self, pthread_getcpuclockid, c_int};
7
8#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
9pub struct ThreadTime {
10 pub last: Duration,
11 pub clk_id: c_int,
12}
13
14impl ThreadTime {
15 pub fn get_clk() -> Result<c_int> {
16 let clk_id: c_int;
17
18 unsafe {
19 let mut v = 3;
20 let clock_id = &mut v as *mut i32;
21 let res = pthread_getcpuclockid(pthread_self(), clock_id);
22 if res != 0 {
23 return Err(Error::last_os_error());
24 }
25 clk_id = *clock_id;
26 }
27
28 Ok(clk_id)
29 }
30
31 pub fn query_clk(clk_id: c_int) -> Result<Duration> {
32 let mut time = timespec {
33 tv_sec: 0,
34 tv_nsec: 0,
35 };
36
37 if unsafe { clock_gettime(clk_id, &mut time) } == -1
38 {
39 return Err(Error::last_os_error());
40 }
41 Ok(Duration::new(time.tv_sec as u64, time.tv_nsec as u32))
42 }
43
44 pub fn query(&self) -> Result<Duration> {
45 return Self::query_clk(self.clk_id)
46 }
47
48 pub fn new() -> Self {
49 Self::try_new().unwrap()
50 }
51
52 pub fn try_new() -> Result<Self> {
53 let clk_id = Self::get_clk();
54 if let Err(e) = clk_id {
55 return Err(e);
56 }
57 let clk_id = clk_id.unwrap();
58 let last = Self::query_clk(clk_id);
59 if let Err(e) = last {
60 return Err(e);
61 }
62
63 return Ok(Self {
64 last: last.unwrap(),
65 clk_id: clk_id
66 });
67 }
68
69 pub fn elapsed(&self) -> Duration {
70 self.query().unwrap() - self.last
71 }
72
73 pub fn now(&mut self) {
74 self.last = self.query().unwrap();
75 }
76
77}