1#![cfg_attr(not(feature = "std"), no_std)]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3
4mod interval;
5mod sleep;
6mod timeout;
7mod waiter;
8
9use core::time::Duration;
10pub use interval::*;
11pub use sleep::*;
12pub use timeout::*;
13use waiter::Waiter;
14
15const WAITS_NUM: usize = 64;
16static WAITS: Waiter<WAITS_NUM> = Waiter::new();
17
18pub fn now() -> u64 {
20 tick_clock::now()
21}
22
23pub struct Tick {
24 tick: tick_clock::Tick,
25}
26impl Tick {
27 pub fn tick(&mut self, interval: Duration) -> u64 {
29 let now = self.tick.tick(interval);
30 if let Some(next) = WAITS.take_next() {
31 if now < next {
32 WAITS.set_next(next);
33 return now;
34 }
35 } else {
36 return now;
37 }
38 let mut min = u64::MAX;
39 WAITS.retain(|entity| {
40 if **entity <= now {
41 entity.wake();
42 false
43 } else {
44 min = min.min(**entity);
45 true
46 }
47 });
48 WAITS.set_next(min);
49 now
50 }
51}
52pub fn take_tick() -> Option<Tick> {
53 tick_clock::take_tick().map(|tick| Tick { tick })
54}
55
56#[cfg(feature = "std")]
57#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
58pub fn auto_tick(interval: Duration) {
59 use std::thread;
60 use std::time::Instant;
61
62 let mut ticker = take_tick().unwrap();
63 let mut last = Instant::now();
64 thread::Builder::new()
65 .name("async-tick".into())
66 .spawn(move || loop {
67 let now = Instant::now();
68 ticker.tick(now.saturating_duration_since(last));
69 last = now;
70 thread::sleep(interval);
71 })
72 .unwrap();
73}