os_trait/
os_impls.rs

1use crate::{
2    mutex_impls::*,
3    notifier_impls::*,
4    prelude::*,
5    timeout_trait::{delay::*, fake_impls::*},
6};
7cfg_if::cfg_if! {
8    if #[cfg(feature = "std")] {
9        use std::thread;
10        use crate::timeout_trait::std_impls::*;
11    }
12}
13
14// STD --------------------------------------------------------------
15
16/// This implementation is only for unit testing.
17pub struct StdOs;
18#[cfg(feature = "std")]
19impl OsInterface for StdOs {
20    type RawMutex = FakeRawMutex;
21    type Notifier = StdNotifier;
22    type NotifyWaiter = StdNotifyWaiter;
23    type Instant = StdTickInstant;
24    type Delay = StdDelayNs;
25
26    const O: Self = Self {};
27
28    #[inline]
29    fn yield_thread() {
30        thread::yield_now();
31    }
32
33    #[inline]
34    fn delay() -> Self::Delay {
35        StdDelayNs {}
36    }
37
38    #[inline]
39    fn notify() -> (Self::Notifier, Self::NotifyWaiter) {
40        StdNotifier::new()
41    }
42}
43
44// Fake -------------------------------------------------------------
45
46pub struct FakeOs;
47impl OsInterface for FakeOs {
48    type RawMutex = FakeRawMutex;
49    type Notifier = FakeNotifier;
50    type NotifyWaiter = FakeNotifier;
51    type Instant = FakeTickInstant;
52    type Delay = TickDelay<FakeTickInstant>;
53
54    const O: Self = Self {};
55
56    #[inline]
57    fn yield_thread() {}
58
59    #[inline]
60    fn delay() -> Self::Delay {
61        TickDelay::<FakeTickInstant>::default()
62    }
63
64    #[inline]
65    fn notify() -> (Self::Notifier, Self::NotifyWaiter) {
66        FakeNotifier::new()
67    }
68}
69
70// Tests ------------------------------------------------------------
71
72#[cfg(feature = "std")]
73#[cfg(test)]
74mod tests {
75    use super::*;
76    use crate::{Duration, Timeout};
77
78    struct OsUser<OS: OsInterface> {
79        notifier: OS::Notifier,
80        waiter: OS::NotifyWaiter,
81        mutex: Mutex<OS, u8>,
82        interval: Timeout<OS>,
83    }
84
85    impl<OS: OsInterface> OsUser<OS> {
86        fn new() -> Self {
87            let (notifier, waiter) = OS::notify();
88            Self {
89                notifier,
90                waiter,
91                mutex: OS::mutex(1),
92                interval: Timeout::<OS>::from_millis(1),
93            }
94        }
95
96        fn use_os(&mut self) {
97            let mutex = OS::mutex(0);
98
99            let mut guard = mutex.try_lock().unwrap();
100            assert_eq!(*guard, 0);
101            *guard = 4;
102            drop(guard);
103
104            mutex
105                .try_with_lock(|data| {
106                    assert_eq!(*data, 4);
107                    *data = 5;
108                })
109                .unwrap();
110
111            OS::yield_thread();
112            OS::delay().delay_ms(1);
113
114            let _os = OS::O;
115
116            assert!(self.notifier.notify());
117            assert!(self.waiter.wait(&Duration::<OS>::from_millis(1)));
118
119            let mut d = self.mutex.lock();
120            *d = 2;
121
122            if self.interval.timeout() {}
123        }
124    }
125
126    #[test]
127    fn select_os() {
128        let mut user = OsUser::<FakeOs>::new();
129        user.use_os();
130        let mut user = OsUser::<StdOs>::new();
131        user.use_os();
132    }
133}