1use core::sync::atomic::{AtomicUsize, Ordering};
2const LOCK_UNOWNED: usize = 0;
3
4pub struct Mutex {
6 owner: AtomicUsize,
7}
8
9pub struct LockToken(bool);
10
11impl Mutex {
12 pub const fn new() -> Self {
13 Self {
14 owner: AtomicUsize::new(LOCK_UNOWNED),
15 }
16 }
17
18 pub fn lock(&self) -> LockToken {
19 let hart_id = crate::hart_id();
20 if self.owner.load(Ordering::Acquire) == hart_id {
21 return LockToken(false);
22 }
23 loop {
24 if self
25 .owner
26 .compare_exchange(LOCK_UNOWNED, hart_id, Ordering::AcqRel, Ordering::Acquire)
27 .is_ok()
28 {
29 break;
30 }
31 }
32 LockToken(true)
33 }
34 pub fn release(&self, lock_token: LockToken) {
35 if lock_token.0 {
36 self.owner.store(LOCK_UNOWNED, Ordering::Release);
37 }
38 }
39}