1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// Copyright Open Logistics Foundation
//
// Licensed under the Open Logistics Foundation License 1.3.
// For details on the licensing terms, see the LICENSE file.
// SPDX-License-Identifier: OLFL-1.3
use Duration;
use crateInstant;
/// Clock trait for clocks which are expected to be always running and never fail
///
/// The trait has an associated type `Instant` which needs to implement the [`Instant`] trait. For
/// most users of this trait, it should be fine to keep this type generic and not further restrict
/// it. This will keep the code compatible with all clock implementations and improve
/// platform-independence. If a specific type is required for whatever reason, the
/// [`instant`](crate::instant) module defines some types which could be used by clock
/// implementers. Keep in mind though, that even if the `Instant` type would support
/// high-resolution clocks, this does not guarantee that the underlying clock actually supports
/// that resolution. Therefore, clock resolution requirements need to be documented in a different
/// way.
///
/// The design decision to define the clock trait as infallible has been made because handling
/// clock errors is often extremely difficult. Experience has shown that clock users tend to
/// `unwrap` on all clock interactions, if not directly then at least eventually after propagating
/// errors as far as they could. Having an infallible clock trait is cleaner because it
/// communicates that clock implementers need to make sure that the clock is always working, at
/// least for the time it is available to the clock users. If, for some reason, working with a
/// fallible clock is required, an approach might be to use a (properly synchronized) global
/// `Option<&impl Clock>` which is set to `None` whenever the clock is not available. But this use
/// case is explicitly not supported or advocated for by this crate.
///
/// Since the [`Instant`] trait could not contain the
/// [`std::time::Instant::elapsed`](https://doc.rust-lang.org/stable/std/time/struct.Instant.html#method.elapsed)
/// method which depends on a global clock, this method is moved here in addition to the
/// [`now`](Clock::now) method.
///
/// All methods in this trait require shared `&` references so that a single clock reference can be
/// shared and used for a whole application. This might be in contrast to many embedded approaches
/// in which such hardware-related accesses are often done via an exclusive `&mut` reference. But in
/// fact, this trait is not designed to describe exclusive access to a hardware clock (with the
/// possibility to start, stop or reconfigure it), but to gain access to a virtually global shared
/// clock. To allow this, clock implementers need to use an effective synchronization or locking
/// mechanism to allow such accesses.