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}