os_trait/
os_impls.rs

1use crate::{
2    mutex_impls::*,
3    notifier_impls::*,
4    prelude::*,
5    timeout_trait::{delay_impls::*, 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 Timeout = StdTimeoutNs;
24
25    const O: Self = Self {};
26
27    #[inline]
28    fn yield_thread() {
29        thread::yield_now();
30    }
31
32    #[inline]
33    fn delay() -> impl DelayNs {
34        StdDelayNs {}
35    }
36
37    #[inline]
38    fn notify() -> (Self::Notifier, Self::NotifyWaiter) {
39        StdNotifier::new()
40    }
41}
42
43// Fake -------------------------------------------------------------
44
45pub struct FakeOs;
46impl OsInterface for FakeOs {
47    type RawMutex = FakeRawMutex;
48    type Notifier = FakeNotifier;
49    type NotifyWaiter = FakeNotifier;
50    type Timeout = FakeTimeoutNs;
51
52    const O: Self = Self {};
53
54    #[inline]
55    fn yield_thread() {}
56
57    #[inline]
58    fn delay() -> impl DelayNs {
59        TickDelay::<FakeInstant>::default()
60    }
61
62    #[inline]
63    fn notify() -> (Self::Notifier, Self::NotifyWaiter) {
64        FakeNotifier::new()
65    }
66}
67
68// Tests ------------------------------------------------------------
69
70#[cfg(feature = "std")]
71#[cfg(test)]
72mod tests {
73    use super::*;
74    use crate::fugit::ExtU32;
75
76    struct OsUser<OS: OsInterface> {
77        notifier: OS::Notifier,
78        waiter: OS::NotifyWaiter,
79        mutex: Mutex<OS, u8>,
80    }
81
82    impl<OS: OsInterface> OsUser<OS> {
83        fn new() -> Self {
84            let (notifier, waiter) = OS::notify();
85            Self {
86                notifier,
87                waiter,
88                mutex: OS::mutex(1),
89            }
90        }
91
92        fn use_os(&mut self) {
93            let mutex = OS::mutex(0);
94
95            let mut guard = mutex.try_lock().unwrap();
96            assert_eq!(*guard, 0);
97            *guard = 4;
98            drop(guard);
99
100            mutex
101                .try_with_lock(|data| {
102                    assert_eq!(*data, 4);
103                    *data = 5;
104                })
105                .unwrap();
106
107            OS::yield_thread();
108            OS::delay().delay_ms(1);
109
110            let _os = OS::O;
111
112            assert!(self.notifier.notify());
113            assert!(self.waiter.wait(1.millis()));
114
115            let mut d = self.mutex.lock();
116            *d = 2;
117        }
118    }
119
120    #[test]
121    fn select_os() {
122        let mut user = OsUser::<FakeOs>::new();
123        user.use_os();
124        let mut user = OsUser::<StdOs>::new();
125        user.use_os();
126    }
127}