os_sync/mutex/
sem.rs

1use crate::sem::Semaphore;
2
3use core::sync::atomic::{AtomicU32, Ordering};
4
5///Semaphore based implementation, often called Benaphore
6///
7///Note that it is not recursive
8pub struct Mutex<T> {
9    sem: T,
10    count: AtomicU32,
11}
12
13impl<T: Semaphore> super::Mutex for Mutex<T> {
14    #[inline]
15    fn new() -> Option<Self> {
16        Some(Self {
17            sem: T::new(0)?,
18            count: AtomicU32::new(0),
19        })
20    }
21
22    #[inline]
23    fn lock(&self) -> super::MutexGuard<'_, Self> {
24        if self.count.fetch_add(1, Ordering::AcqRel) > 0 {
25            self.sem.wait();
26        }
27
28        super::MutexGuard {
29            mutex: self,
30        }
31    }
32
33    fn try_lock(&self) -> Option<super::MutexGuard<'_, Self>> {
34        if self.count.compare_and_swap(0, 1, Ordering::AcqRel) > 0 {
35            None
36        } else {
37            Some(super::MutexGuard {
38                mutex: self,
39            })
40        }
41    }
42
43    fn unlock(&self, _: super::GuardToken) {
44        let old_count = self.count.fetch_sub(1, Ordering::AcqRel);
45
46        //This is not possible for user as he only uses guard
47        debug_assert_ne!(old_count, 0);
48
49        self.sem.signal()
50    }
51}