mpfs_hal/
mutex.rs

1use core::sync::atomic::{AtomicUsize, Ordering};
2const LOCK_UNOWNED: usize = 0;
3
4/// A Mutex that does not protect against interrupts, but does protect against other cores
5pub 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}