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