emerald_std/sync/spin/lock.rs
1use core::{
2 hint,
3 sync::atomic::{AtomicBool, Ordering},
4};
5
6/// A raw spin lock, only provides `lock` and `unlock` and waiting for the lock
7///
8/// This is an unsafe lock, it doesn't have any protection against deadlocks, or multiple locking
9/// A safe wrappers are implemented with `Mutex` and `ReMutex`
10pub(super) struct Lock {
11 // we still use `bool` that is not cache aligned
12 // because this will change in the future to use os mutexes, and better synchronization methods
13 locked: AtomicBool,
14}
15
16impl Lock {
17 pub const fn new() -> Self {
18 Self {
19 locked: AtomicBool::new(false),
20 }
21 }
22
23 pub fn lock(&self) {
24 while !self.try_lock() {
25 while self.locked.load(Ordering::Relaxed) {
26 hint::spin_loop();
27 }
28 }
29 }
30
31 #[must_use]
32 #[inline(always)]
33 /// Try to lock the lock, returns true if successful
34 pub fn try_lock(&self) -> bool {
35 self.locked
36 .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
37 .is_ok()
38 }
39
40 /// SAFETY: the caller must assure that there is only one accessor for this lock
41 /// we don't want multiple unlocks, it doesn't make sense for this Lock (check `super::remutex::ReMutex`)
42 pub unsafe fn unlock(&self) {
43 self.locked.store(false, Ordering::Release);
44 }
45}