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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//! [`SleepPrecise`]: a sleep that ends at its deadline to the microsecond,
//! off the millisecond wheel.
//!
//! A precise timer is armed in its shard's microsecond wheel (the same wheel
//! as the millisecond one, counting microseconds), and the shard's wait ends
//! at the earliest deadline of either wheel through the backend's
//! high-resolution timer: the wait's own timeout on io_uring (its hrtimer has
//! no slack) and on Windows (a high-resolution waitable timer), a timerfd on
//! epoll (whose own timeout counts milliseconds), and an `EVFILT_TIMER` in
//! nanoseconds on kqueue. A paused clock moves to a precise deadline exactly.
use fmt;
use Future;
use Pin;
use ;
use Duration;
use Instant;
use ;
/// Waits until `duration` has passed, to the microsecond.
///
/// The wait is at least `duration`, rounded up to the microsecond, and ends
/// as soon after that as the system's timer wakes the shard; a busy shard
/// may let it run later by the time its current task takes to yield. Use it
/// where the millisecond of [`sleep`](super::sleep) is too coarse: a pacer, a
/// retry spaced in microseconds, a deadline a protocol counts in
/// microseconds. Each precise deadline that is the shard's earliest costs
/// the shard a timer of its own in the kernel (one system call to arm it on
/// epoll), so a coarse sleep stays the cheaper choice where a millisecond is
/// fine.
///
/// ```
/// use std::time::Duration;
/// use nuclei::time::{self, Instant};
///
/// # nuclei::Builder::new().worker_threads(0).build().unwrap().block_on(async {
/// time::pause();
/// let start = Instant::now();
/// time::sleep_precise(Duration::from_micros(250)).await;
/// // A paused clock moves to the deadline itself: not a millisecond later.
/// assert_eq!(start.elapsed(), Duration::from_micros(250));
/// # });
/// ```
/// Waits until `deadline`, to the microsecond (see [`sleep_precise`]).
/// A future that completes at its deadline, to the microsecond. Made by
/// [`sleep_precise`] and [`sleep_until_precise`].
///
/// Polled on one of nuclei's shards, it arms a timer in that shard's
/// microsecond wheel; polled anywhere else (another runtime's thread), it
/// asks a shard of the current runtime (or the default one) to fire it.
/// Dropping it cancels the timer.