freertos_rust/
semaphore.rs

1use crate::base::*;
2use crate::units::*;
3use crate::shim::*;
4
5/// A counting or binary semaphore
6pub struct Semaphore {
7    semaphore: FreeRtosSemaphoreHandle,
8}
9
10unsafe impl Send for Semaphore {}
11unsafe impl Sync for Semaphore {}
12
13impl Semaphore {
14    /// Create a new binary semaphore
15    pub fn new_binary() -> Result<Semaphore, FreeRtosError> {
16        unsafe {
17            let s = freertos_rs_create_binary_semaphore();
18            if s == 0 as *const _ {
19                return Err(FreeRtosError::OutOfMemory);
20            }
21            Ok(Semaphore { semaphore: s })
22        }
23    }
24
25    /// Create a new counting semaphore
26    pub fn new_counting(max: u32, initial: u32) -> Result<Semaphore, FreeRtosError> {
27        unsafe {
28            let s = freertos_rs_create_counting_semaphore(max, initial);
29            if s == 0 as *const _ {
30                return Err(FreeRtosError::OutOfMemory);
31            }
32            Ok(Semaphore { semaphore: s })
33        }
34    }
35    
36    /// Lock this semaphore in a RAII fashion
37    pub fn lock<D: DurationTicks>(&self, max_wait: D) -> Result<SemaphoreGuard, FreeRtosError> {
38        unsafe {
39            let res = freertos_rs_take_mutex(self.semaphore, max_wait.to_ticks());
40
41            if res != 0 {
42                return Err(FreeRtosError::Timeout);
43            }
44
45            Ok(SemaphoreGuard { __semaphore: self.semaphore })
46        }
47    }
48}
49
50impl Drop for Semaphore {
51    fn drop(&mut self) {
52        unsafe {
53            freertos_rs_delete_semaphore(self.semaphore);
54        }
55    }
56}
57
58/// Holds the lock to the semaphore until we are dropped
59pub struct SemaphoreGuard {
60    __semaphore: FreeRtosSemaphoreHandle,
61}
62
63impl Drop for SemaphoreGuard {
64    fn drop(&mut self) {
65        unsafe {
66            freertos_rs_give_mutex(self.__semaphore);
67        }
68    }
69}