1#![no_std]
2
3extern crate idem;
4
5#[cfg(feature = "libc")]
6extern crate libc;
7
8#[cfg(feature = "system-call")]
9#[macro_use]
10extern crate syscall;
11
12use core::ops::*;
13use idem::Zero;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
16pub struct Span(i128);
17
18impl Span {
19    #[inline]
20    pub fn from_ns(ns: i128) -> Self { Span(ns) }
21    #[inline]
22    pub fn to_ns(self) -> i128 { self.0 }
23
24    #[cfg(feature = "libc")]
25    #[inline]
26    pub fn to_c_timespec(self) -> Option<::libc::timespec> {
27        let b = 1_000_000_000;
28        let s = (self.0 / b) as ::libc::time_t;
29        if self.0 / b == s as i128 {
30            Some(::libc::timespec { tv_sec: s, tv_nsec: (self.0 % b) as _ })
31        } else { None }
32    }
33}
34
35impl Zero for Span {
36    const zero: Self = Span(0);
37}
38
39impl Add for Span {
40    type Output = Self;
41    #[inline]
42    fn add(self, other: Self) -> Self { Span(self.0 + other.0) }
43}
44
45impl Sub for Span {
46    type Output = Self;
47    #[inline]
48    fn sub(self, other: Self) -> Self { Span(self.0 - other.0) }
49}
50
51impl AddAssign for Span {
52    #[inline]
53    fn add_assign(&mut self, other: Self) { self.0 += other.0 }
54}
55
56impl SubAssign for Span {
57    #[inline]
58    fn sub_assign(&mut self, other: Self) { self.0 -= other.0 }
59}
60
61#[cfg(feature = "libc")]
62impl From<::libc::timespec> for Span {
63    #[inline]
64    fn from(ts: ::libc::timespec) -> Self {
65        Span(1_000_000_000*(ts.tv_sec as i128) + (ts.tv_nsec as i128))
66    }
67}
68
69#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
70pub struct Point(i128);
71
72#[cfg(feature = "posix")]
73impl Point {
74    #[inline]
75    pub fn now() -> Self { unsafe {
76        let mut ts: ::libc::timespec = ::core::mem::MaybeUninit::uninit().assume_init();
77        syscall!(CLOCK_GETTIME, ::libc::CLOCK_MONOTONIC, &mut ts as *mut _);
78        Point(Span::from(ts).0)
79    } }
80
81    #[inline]
82    pub fn elapsed(self) -> Span { Self::now() - self }
83}
84
85impl Add<Span> for Point {
86    type Output = Self;
87    #[inline]
88    fn add(self, other: Span) -> Self { Point(self.0 + other.0) }
89}
90
91impl Sub<Span> for Point {
92    type Output = Self;
93    #[inline]
94    fn sub(self, other: Span) -> Self { Point(self.0 - other.0) }
95}
96
97impl Sub for Point {
98    type Output = Span;
99    #[inline]
100    fn sub(self, other: Self) -> Span { Span(self.0 - other.0) }
101}
102
103impl AddAssign<Span> for Point {
104    #[inline]
105    fn add_assign(&mut self, other: Span) { self.0 += other.0 }
106}
107
108impl SubAssign<Span> for Point {
109    #[inline]
110    fn sub_assign(&mut self, other: Span) { self.0 -= other.0 }
111}