1use crate::sem::Semaphore;
2
3use core::sync::atomic::{AtomicU32, Ordering};
4
5pub 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 debug_assert_ne!(old_count, 0);
48
49 self.sem.signal()
50 }
51}