Skip to main content

UnixClock

Struct UnixClock 

Source
pub struct UnixClock<Timescale> { /* private fields */ }
Expand description

A Unix OS clock

Implementations§

Source§

impl UnixClock<UTC>

Source

pub const CLOCK_REALTIME: Self

The standard realtime clock on unix systems.

use clock_steering::unix::UnixClock;
use statime_base::Clock;

fn main() {
    let clock = UnixClock::CLOCK_REALTIME;
    let now = clock.now().unwrap();

    println!("{now:?}");
}
Source§

impl UnixClock<TAI>

Source

pub const CLOCK_TAI: Self

TAI time on linux systems.

use clock_steering::unix::UnixClock;
use statime_base::Clock;

fn main() {
    let clock = UnixClock::CLOCK_TAI;
    let now = clock.now().unwrap();

    println!("{now:?}");
}
Source

pub fn open(path: impl AsRef<Path>) -> Result<Self>

Open a clock device.

use clock_steering::unix::UnixClock;
use statime_base::Clock;

fn main() {
    let clock = UnixClock::open("/dev/ptp0").unwrap();
    let now = clock.now().unwrap();

    println!("{now:?}");
}
§Errors

Returns an error if the given path cannot be opened.

Examples found in repository?
examples/basic.rs (line 18)
10fn main() -> Result<(), Box<dyn std::error::Error>> {
11    #[cfg(target_os = "linux")]
12    let arg = std::env::args().nth(1);
13
14    #[cfg(target_os = "linux")]
15    match arg.as_deref() {
16        None | Some("realtime") => exercise_clock(UnixClock::CLOCK_REALTIME),
17        Some("tai") => exercise_clock(UnixClock::CLOCK_TAI),
18        Some(path) if path.starts_with("/dev/") => exercise_clock(UnixClock::open(path)?),
19        Some(other) => {
20            eprintln!("unknown clock: {other}");
21            eprintln!("usage: basic [realtime|tai|/dev/ptpN]");
22            std::process::exit(1);
23        }
24    }
25
26    #[cfg(not(target_os = "linux"))]
27    exercise_clock(UnixClock::CLOCK_REALTIME)
28}
Source

pub fn system_offset( &self, ) -> Result<(Timestamp<TAI>, Timestamp<TAI>, Timestamp<TAI>), ClockError>

Determine offset between file clock and TAI clock (if any) Returns two system timestamps sandwhiching a timestamp from the hardware clock.

§Errors

Returns an error fi the system offset could not be provided.

Source§

impl<Timescale> UnixClock<Timescale>

Source

pub fn disable_kernel(&self) -> Result<(), ClockError>

Disable any kernel disciplining of this clock.

§Errors

May error if the clock has gone away.

Examples found in repository?
examples/basic.rs (line 93)
30fn exercise_clock<Timescale: Send + 'static>(
31    clock: UnixClock<Timescale>,
32) -> Result<(), Box<dyn std::error::Error>> {
33    // Read-only operations
34
35    let now = clock.now()?;
36    let nanos = (now - Timestamp::UNIX_EPOCH).as_nanos();
37    let seconds = nanos / 1_000_000_000;
38    let nanos = nanos % 1_000_000_000;
39    println!("now:         {}.{:09}", seconds, nanos);
40
41    let res = clock.resolution()?;
42    println!("resolution:  {}ns", res.as_nanos());
43
44    let max_freq = clock.max_frequency()?;
45    println!("max freq:    {} ppm", max_freq * 1e6);
46
47    match clock.get_frequency() {
48        Ok(f) => println!("frequency:   {:.6} us/s", f * 1e6),
49        Err(e) => println!("frequency:   {e}"),
50    }
51
52    #[cfg(target_os = "linux")]
53    match clock.get_tai() {
54        Ok(tai) => println!("TAI offset:  {tai}s"),
55        Err(e) => println!("TAI offset:  {e}"),
56    }
57
58    // Write operations — require root
59
60    println!();
61
62    match clock.set_frequency(0.0) {
63        Ok(t) => println!(
64            "set_frequency(0.0):     ok at {}.{:09}",
65            (t - Timestamp::UNIX_EPOCH).as_nanos() / 1_000_000_000,
66            (t - Timestamp::UNIX_EPOCH).as_nanos() % 1_000_000_000
67        ),
68        Err(e) => println!("set_frequency(0.0):     {e}"),
69    }
70
71    match clock.step_clock(Duration::from_seconds_nanos(0, 0)) {
72        Ok(t) => println!(
73            "step_clock(0):          ok at {}.{:09}",
74            (t - Timestamp::UNIX_EPOCH).as_nanos() / 1_000_000_000,
75            (t - Timestamp::UNIX_EPOCH).as_nanos() % 1_000_000_000
76        ),
77        Err(e) => println!("step_clock(0):          {e}"),
78    }
79
80    match clock.leap_update(LeapStatus::None) {
81        Ok(()) => println!("set_leap_seconds:       ok"),
82        Err(e) => println!("set_leap_seconds:       {e}"),
83    }
84
85    match clock.error_estimate_update(
86        Duration::from_seconds_nanos(0, 100_000),
87        Duration::from_seconds_nanos(0, 1_000_000),
88    ) {
89        Ok(()) => println!("error_estimate_update:  ok"),
90        Err(e) => println!("error_estimate_update:  {e}"),
91    }
92
93    match clock.disable_kernel() {
94        Ok(()) => println!("disable_kernel_ntp:     ok"),
95        Err(e) => println!("disable_kernel_ntp:     {e}"),
96    }
97
98    Ok(())
99}
Source

pub fn set_tai(&self, tai_offset: i32) -> Result<(), ClockError>

Set the TAI offset on the given clock.

§Errors

May error if the clock does not support setting the TAI offset.

Source

pub fn get_tai(&self) -> Result<i32, ClockError>

Get the TAI offset on the given clock.

§Errors

May error if the clock does not support getting the TAI offset.

Examples found in repository?
examples/basic.rs (line 53)
30fn exercise_clock<Timescale: Send + 'static>(
31    clock: UnixClock<Timescale>,
32) -> Result<(), Box<dyn std::error::Error>> {
33    // Read-only operations
34
35    let now = clock.now()?;
36    let nanos = (now - Timestamp::UNIX_EPOCH).as_nanos();
37    let seconds = nanos / 1_000_000_000;
38    let nanos = nanos % 1_000_000_000;
39    println!("now:         {}.{:09}", seconds, nanos);
40
41    let res = clock.resolution()?;
42    println!("resolution:  {}ns", res.as_nanos());
43
44    let max_freq = clock.max_frequency()?;
45    println!("max freq:    {} ppm", max_freq * 1e6);
46
47    match clock.get_frequency() {
48        Ok(f) => println!("frequency:   {:.6} us/s", f * 1e6),
49        Err(e) => println!("frequency:   {e}"),
50    }
51
52    #[cfg(target_os = "linux")]
53    match clock.get_tai() {
54        Ok(tai) => println!("TAI offset:  {tai}s"),
55        Err(e) => println!("TAI offset:  {e}"),
56    }
57
58    // Write operations — require root
59
60    println!();
61
62    match clock.set_frequency(0.0) {
63        Ok(t) => println!(
64            "set_frequency(0.0):     ok at {}.{:09}",
65            (t - Timestamp::UNIX_EPOCH).as_nanos() / 1_000_000_000,
66            (t - Timestamp::UNIX_EPOCH).as_nanos() % 1_000_000_000
67        ),
68        Err(e) => println!("set_frequency(0.0):     {e}"),
69    }
70
71    match clock.step_clock(Duration::from_seconds_nanos(0, 0)) {
72        Ok(t) => println!(
73            "step_clock(0):          ok at {}.{:09}",
74            (t - Timestamp::UNIX_EPOCH).as_nanos() / 1_000_000_000,
75            (t - Timestamp::UNIX_EPOCH).as_nanos() % 1_000_000_000
76        ),
77        Err(e) => println!("step_clock(0):          {e}"),
78    }
79
80    match clock.leap_update(LeapStatus::None) {
81        Ok(()) => println!("set_leap_seconds:       ok"),
82        Err(e) => println!("set_leap_seconds:       {e}"),
83    }
84
85    match clock.error_estimate_update(
86        Duration::from_seconds_nanos(0, 100_000),
87        Duration::from_seconds_nanos(0, 1_000_000),
88    ) {
89        Ok(()) => println!("error_estimate_update:  ok"),
90        Err(e) => println!("error_estimate_update:  {e}"),
91    }
92
93    match clock.disable_kernel() {
94        Ok(()) => println!("disable_kernel_ntp:     ok"),
95        Err(e) => println!("disable_kernel_ntp:     {e}"),
96    }
97
98    Ok(())
99}
Source

pub fn resolution(&self) -> Result<Duration, ClockError>

Get the clock’s resolution.

The output Timestamp will be all zeros when the resolution is unavailable.

§Errors

May error if the clcok has gone away

Examples found in repository?
examples/basic.rs (line 41)
30fn exercise_clock<Timescale: Send + 'static>(
31    clock: UnixClock<Timescale>,
32) -> Result<(), Box<dyn std::error::Error>> {
33    // Read-only operations
34
35    let now = clock.now()?;
36    let nanos = (now - Timestamp::UNIX_EPOCH).as_nanos();
37    let seconds = nanos / 1_000_000_000;
38    let nanos = nanos % 1_000_000_000;
39    println!("now:         {}.{:09}", seconds, nanos);
40
41    let res = clock.resolution()?;
42    println!("resolution:  {}ns", res.as_nanos());
43
44    let max_freq = clock.max_frequency()?;
45    println!("max freq:    {} ppm", max_freq * 1e6);
46
47    match clock.get_frequency() {
48        Ok(f) => println!("frequency:   {:.6} us/s", f * 1e6),
49        Err(e) => println!("frequency:   {e}"),
50    }
51
52    #[cfg(target_os = "linux")]
53    match clock.get_tai() {
54        Ok(tai) => println!("TAI offset:  {tai}s"),
55        Err(e) => println!("TAI offset:  {e}"),
56    }
57
58    // Write operations — require root
59
60    println!();
61
62    match clock.set_frequency(0.0) {
63        Ok(t) => println!(
64            "set_frequency(0.0):     ok at {}.{:09}",
65            (t - Timestamp::UNIX_EPOCH).as_nanos() / 1_000_000_000,
66            (t - Timestamp::UNIX_EPOCH).as_nanos() % 1_000_000_000
67        ),
68        Err(e) => println!("set_frequency(0.0):     {e}"),
69    }
70
71    match clock.step_clock(Duration::from_seconds_nanos(0, 0)) {
72        Ok(t) => println!(
73            "step_clock(0):          ok at {}.{:09}",
74            (t - Timestamp::UNIX_EPOCH).as_nanos() / 1_000_000_000,
75            (t - Timestamp::UNIX_EPOCH).as_nanos() % 1_000_000_000
76        ),
77        Err(e) => println!("step_clock(0):          {e}"),
78    }
79
80    match clock.leap_update(LeapStatus::None) {
81        Ok(()) => println!("set_leap_seconds:       ok"),
82        Err(e) => println!("set_leap_seconds:       {e}"),
83    }
84
85    match clock.error_estimate_update(
86        Duration::from_seconds_nanos(0, 100_000),
87        Duration::from_seconds_nanos(0, 1_000_000),
88    ) {
89        Ok(()) => println!("error_estimate_update:  ok"),
90        Err(e) => println!("error_estimate_update:  {e}"),
91    }
92
93    match clock.disable_kernel() {
94        Ok(()) => println!("disable_kernel_ntp:     ok"),
95        Err(e) => println!("disable_kernel_ntp:     {e}"),
96    }
97
98    Ok(())
99}

Trait Implementations§

Source§

impl<Timescale: Send + 'static> Clock<Timescale> for UnixClock<Timescale>

Source§

fn now(&self) -> Result<Timestamp<Timescale>, ClockError>

Get current time Read more
Source§

fn set_frequency(&self, freq: f64) -> Result<Timestamp<Timescale>, ClockError>

Change the frequency of the clock, returning the time at which the change was applied. The frequency is in seconds per second deviation. Read more
Source§

fn get_frequency(&self) -> Result<f64, ClockError>

Get the frequency of the clock, in seconds per second deviation Read more
Source§

fn max_frequency(&self) -> Result<f64, ClockError>

Maximum frequency offset the clock is capable of, in seconds per second deviation. Read more
Source§

fn step_clock( &self, offset: Duration, ) -> Result<Timestamp<Timescale>, ClockError>

Change the current time of the clock by offset. Returns the time at which the change was applied. Read more
Source§

fn error_estimate_update( &self, est_error: Duration, max_error: Duration, ) -> Result<(), ClockError>

Provide the system with our current best estimates for the statistical error of the clock (est_error), and the maximum deviation due to frequency error and distance to the root clock. Read more
Source§

fn leap_update(&self, leap_status: LeapStatus) -> Result<(), ClockError>

Change the indicators for upcoming leap seconds. Application should happen at the end of the UTC month. Read more
Source§

fn synchronization_update(&self, synchronized: bool) -> Result<(), ClockError>

Change the synchronization indicator. Read more
Source§

impl<Timescale> Clone for UnixClock<Timescale>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<Timescale> Copy for UnixClock<Timescale>

Source§

impl<Timescale> Debug for UnixClock<Timescale>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<Timescale> Forget for UnixClock<Timescale>

§

impl<Timescale> Freeze for UnixClock<Timescale>
where PhantomData<Timescale>: Freeze,

§

impl<Timescale> Move for UnixClock<Timescale>

§

impl<Timescale> RefUnwindSafe for UnixClock<Timescale>
where PhantomData<Timescale>: RefUnwindSafe,

§

impl<Timescale> Send for UnixClock<Timescale>
where PhantomData<Timescale>: Send,

§

impl<Timescale> Sync for UnixClock<Timescale>
where PhantomData<Timescale>: Sync,

§

impl<Timescale> Unpin for UnixClock<Timescale>
where PhantomData<Timescale>: Unpin,

§

impl<Timescale> UnsafeUnpin for UnixClock<Timescale>
where PhantomData<Timescale>: UnsafeUnpin,

§

impl<Timescale> UnwindSafe for UnixClock<Timescale>
where PhantomData<Timescale>: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.