]> git.proxmox.com Git - rustc.git/blob - library/std/src/sys/sgx/mutex.rs
New upstream version 1.65.0+dfsg1
[rustc.git] / library / std / src / sys / sgx / mutex.rs
1 use super::waitqueue::{try_lock_or_false, SpinMutex, WaitQueue, WaitVariable};
2 use crate::sys_common::lazy_box::{LazyBox, LazyInit};
3
4 pub struct Mutex {
5 inner: SpinMutex<WaitVariable<bool>>,
6 }
7
8 // not movable: see UnsafeList implementation
9 pub(crate) type MovableMutex = LazyBox<Mutex>;
10
11 impl LazyInit for Mutex {
12 fn init() -> Box<Self> {
13 Box::new(Self::new())
14 }
15 }
16
17 // Implementation according to “Operating Systems: Three Easy Pieces”, chapter 28
18 impl Mutex {
19 pub const fn new() -> Mutex {
20 Mutex { inner: SpinMutex::new(WaitVariable::new(false)) }
21 }
22
23 #[inline]
24 pub unsafe fn lock(&self) {
25 let mut guard = self.inner.lock();
26 if *guard.lock_var() {
27 // Another thread has the lock, wait
28 WaitQueue::wait(guard, || {})
29 // Another thread has passed the lock to us
30 } else {
31 // We are just now obtaining the lock
32 *guard.lock_var_mut() = true;
33 }
34 }
35
36 #[inline]
37 pub unsafe fn unlock(&self) {
38 let guard = self.inner.lock();
39 if let Err(mut guard) = WaitQueue::notify_one(guard) {
40 // No other waiters, unlock
41 *guard.lock_var_mut() = false;
42 } else {
43 // There was a thread waiting, just pass the lock
44 }
45 }
46
47 #[inline]
48 pub unsafe fn try_lock(&self) -> bool {
49 let mut guard = try_lock_or_false!(self.inner);
50 if *guard.lock_var() {
51 // Another thread has the lock
52 false
53 } else {
54 // We are just now obtaining the lock
55 *guard.lock_var_mut() = true;
56 true
57 }
58 }
59 }