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