1use std::cell::{Cell, UnsafeCell};
8use std::ops::{Deref, DerefMut};
9use std::time::Duration;
10
11use crate::thread::{self, FOREVER};
12
13fn addr<T: ?Sized>(x: &T) -> usize {
14 x as *const T as *const u8 as usize
15}
16
17pub struct Mutex<T: ?Sized> {
20 owner: Cell<u64>,
21 data: UnsafeCell<T>,
22}
23
24unsafe impl<T: ?Sized> Sync for Mutex<T> {}
26unsafe impl<T: ?Sized> Send for Mutex<T> {}
27
28impl<T> Mutex<T> {
29 pub const fn new(value: T) -> Mutex<T> {
30 Mutex { owner: Cell::new(0), data: UnsafeCell::new(value) }
31 }
32 pub fn into_inner(self) -> T {
33 self.data.into_inner()
34 }
35}
36
37impl<T: ?Sized> Mutex<T> {
38 pub fn lock(&self) -> MutexGuard<'_, T> {
40 while self.owner.get() != 0 {
41 thread::block(addr(self), FOREVER);
42 }
43 self.owner.set(thread::current().0);
44 MutexGuard { lock: self }
45 }
46 pub fn try_lock(&self) -> Option<MutexGuard<'_, T>> {
48 if self.owner.get() != 0 {
49 return None;
50 }
51 self.owner.set(thread::current().0);
52 Some(MutexGuard { lock: self })
53 }
54 pub fn get_mut(&mut self) -> &mut T {
55 self.data.get_mut()
56 }
57 fn unlock(&self) {
58 self.owner.set(0);
59 thread::wake(addr(self), true);
60 }
61}
62
63impl<T: Default> Default for Mutex<T> {
64 fn default() -> Self {
65 Mutex::new(T::default())
66 }
67}
68
69pub struct MutexGuard<'a, T: ?Sized> {
71 lock: &'a Mutex<T>,
72}
73
74impl<T: ?Sized> Deref for MutexGuard<'_, T> {
75 type Target = T;
76 fn deref(&self) -> &T {
77 unsafe { &*self.lock.data.get() }
78 }
79}
80impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
81 fn deref_mut(&mut self) -> &mut T {
82 unsafe { &mut *self.lock.data.get() }
83 }
84}
85impl<T: ?Sized> Drop for MutexGuard<'_, T> {
86 fn drop(&mut self) {
87 self.lock.unlock();
88 }
89}
90
91#[derive(Clone, Copy, Debug, PartialEq, Eq)]
93pub struct WaitTimeoutResult(bool);
94impl WaitTimeoutResult {
95 pub fn timed_out(&self) -> bool {
96 self.0
97 }
98}
99
100#[derive(Default)]
102pub struct Condvar {
103 _id: u8,
105}
106
107impl Condvar {
108 pub const fn new() -> Condvar {
109 Condvar { _id: 0 }
110 }
111 pub fn wait<'a, T: ?Sized>(&self, guard: MutexGuard<'a, T>) -> MutexGuard<'a, T> {
113 self.wait_deadline(guard, FOREVER).0
114 }
115 pub fn wait_timeout<'a, T: ?Sized>(&self, guard: MutexGuard<'a, T>, d: Duration) -> (MutexGuard<'a, T>, WaitTimeoutResult) {
117 self.wait_deadline(guard, crate::time_ms() + d.as_secs_f64() * 1000.0)
118 }
119 pub fn wait_while<'a, T: ?Sized>(&self, mut guard: MutexGuard<'a, T>, mut condition: impl FnMut(&mut T) -> bool) -> MutexGuard<'a, T> {
121 while condition(&mut *guard) {
122 guard = self.wait(guard);
123 }
124 guard
125 }
126 fn wait_deadline<'a, T: ?Sized>(&self, guard: MutexGuard<'a, T>, deadline: f64) -> (MutexGuard<'a, T>, WaitTimeoutResult) {
127 let lock = guard.lock;
128 drop(guard);
129 let timed_out = thread::block(addr(self), deadline);
130 (lock.lock(), WaitTimeoutResult(timed_out))
131 }
132 pub fn notify_one(&self) {
133 thread::wake(addr(self), true);
134 }
135 pub fn notify_all(&self) {
136 thread::wake(addr(self), false);
137 }
138}
139
140pub struct Semaphore {
142 count: Cell<u32>,
143}
144
145unsafe impl Sync for Semaphore {}
146
147impl Semaphore {
148 pub const fn new(count: u32) -> Semaphore {
149 Semaphore { count: Cell::new(count) }
150 }
151 pub fn acquire(&self) {
153 self.acquire_deadline(FOREVER);
154 }
155 pub fn acquire_timeout(&self, d: Duration) -> bool {
157 self.acquire_deadline(crate::time_ms() + d.as_secs_f64() * 1000.0)
158 }
159 pub fn try_acquire(&self) -> bool {
160 let n = self.count.get();
161 if n == 0 {
162 return false;
163 }
164 self.count.set(n - 1);
165 true
166 }
167 pub fn release(&self) {
168 self.count.set(self.count.get() + 1);
169 thread::wake(addr(self), true);
170 }
171 pub fn count(&self) -> u32 {
172 self.count.get()
173 }
174 fn acquire_deadline(&self, deadline: f64) -> bool {
175 while self.count.get() == 0 {
176 if thread::block(addr(self), deadline) {
177 return self.try_acquire();
178 }
179 }
180 self.count.set(self.count.get() - 1);
181 true
182 }
183}