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