freertos_rust/
critical.rs

1use crate::prelude::v1::*;
2use crate::base::*;
3use crate::shim::*;
4
5pub struct CriticalRegion;
6impl CriticalRegion {
7    pub fn enter() -> Self {
8        unsafe { freertos_rs_enter_critical(); }
9
10        CriticalRegion
11    }
12}
13
14impl Drop for CriticalRegion {
15    fn drop(&mut self) {
16        unsafe { freertos_rs_exit_critical(); }
17    }
18}
19
20unsafe impl<T: Sync + Send> Send for ExclusiveData<T> {}
21unsafe impl<T: Sync + Send> Sync for ExclusiveData<T> {}
22
23/// Data protected with a critical region. Lightweight version of a mutex,
24/// intended for simple data structures.
25pub struct ExclusiveData<T: ?Sized> {
26    data: UnsafeCell<T>
27}
28
29impl<T> ExclusiveData<T> {
30    pub fn new(data: T) -> Self {
31        ExclusiveData {
32            data: UnsafeCell::new(data)
33        }
34    }
35
36    pub fn lock(&self) -> Result<ExclusiveDataGuard<T>, FreeRtosError> {
37        Ok(ExclusiveDataGuard {
38            __data: &self.data,
39            __lock: CriticalRegion::enter()
40        })
41    }
42
43    pub fn lock_from_isr(&self, _context: &mut crate::isr::InterruptContext) -> Result<ExclusiveDataGuardIsr<T>, FreeRtosError> {
44        Ok(ExclusiveDataGuardIsr {
45            __data: &self.data            
46        })
47    }
48}
49
50/// Holds the mutex until we are dropped
51pub struct ExclusiveDataGuard<'a, T: ?Sized + 'a> {
52    __data: &'a UnsafeCell<T>,
53    __lock: CriticalRegion
54}
55
56impl<'mutex, T: ?Sized> Deref for ExclusiveDataGuard<'mutex, T> {
57    type Target = T;
58
59    fn deref<'a>(&'a self) -> &'a T {
60        unsafe { &*self.__data.get() }
61    }
62}
63
64impl<'mutex, T: ?Sized> DerefMut for ExclusiveDataGuard<'mutex, T> {
65    fn deref_mut<'a>(&'a mut self) -> &'a mut T {
66        unsafe { &mut *self.__data.get() }
67    }
68}
69
70
71pub struct ExclusiveDataGuardIsr<'a, T: ?Sized + 'a> {
72    __data: &'a UnsafeCell<T>
73}
74
75impl<'mutex, T: ?Sized> Deref for ExclusiveDataGuardIsr<'mutex, T> {
76    type Target = T;
77
78    fn deref<'a>(&'a self) -> &'a T {
79        unsafe { &*self.__data.get() }
80    }
81}
82
83impl<'mutex, T: ?Sized> DerefMut for ExclusiveDataGuardIsr<'mutex, T> {
84    fn deref_mut<'a>(&'a mut self) -> &'a mut T {
85        unsafe { &mut *self.__data.get() }
86    }
87}