dark_std/sync/
duration.rs1use std::sync::atomic::{AtomicUsize, Ordering};
2use std::time::Duration;
3
4#[derive(Debug)]
6pub struct AtomicDuration(AtomicUsize);
7
8impl AtomicDuration {
9 pub fn new(dur: Option<Duration>) -> Self {
10 let dur = match dur {
11 None => 0,
12 Some(d) => dur_to_ms(d) as usize,
13 };
14 AtomicDuration(AtomicUsize::new(dur))
15 }
16
17 #[inline]
18 pub fn get(&self) -> Option<Duration> {
19 match self.0.load(Ordering::Relaxed) {
20 0 => None,
21 d => Some(Duration::from_millis(d as u64)),
22 }
23 }
24
25 #[inline]
26 pub fn store(&self, dur: Option<Duration>) {
27 let timeout = match dur {
28 None => 0,
29 Some(d) => dur_to_ms(d) as usize,
30 };
31
32 self.0.store(timeout, Ordering::Relaxed);
33 }
34
35 #[inline]
36 pub fn take(&self) -> Option<Duration> {
37 match self.0.swap(0, Ordering::Relaxed) {
38 0 => None,
39 d => Some(Duration::from_millis(d as u64)),
40 }
41 }
42
43 #[inline]
44 pub fn into_inner(self) -> Option<Duration> {
45 self.take()
46 }
47}
48
49fn dur_to_ms(dur: Duration) -> u64 {
50 const MS_PER_SEC: u64 = 1_000;
52 const NANOS_PER_MILLI: u64 = 1_000_000;
53 let ns = u64::from(dur.subsec_nanos());
54 let ms = (ns + NANOS_PER_MILLI - 1) / NANOS_PER_MILLI;
55 dur.as_secs().saturating_mul(MS_PER_SEC).saturating_add(ms)
56}