1use crate::{
2 deadlock,
3 raw_mutex::{TOKEN_HANDOFF, TOKEN_NORMAL},
4 util,
5};
6use core::{
7 cell::Cell,
8 sync::atomic::{AtomicUsize, Ordering},
9};
10use lock_api::{RawRwLock as RawRwLock_, RawRwLockUpgrade};
11use parking_lot_core::{
12 self, FilterOp, ParkResult, ParkToken, SpinWait, UnparkResult, UnparkToken,
13};
14use std::time::{Duration, Instant};
15
16const PARKED_BIT: usize = 0b0001;
30const WRITER_PARKED_BIT: usize = 0b0010;
32const UPGRADABLE_BIT: usize = 0b0100;
35const WRITER_BIT: usize = 0b1000;
38const READERS_MASK: usize = !0b1111;
40const ONE_READER: usize = 0b10000;
42
43const TOKEN_SHARED: ParkToken = ParkToken(ONE_READER);
45const TOKEN_EXCLUSIVE: ParkToken = ParkToken(WRITER_BIT);
46const TOKEN_UPGRADABLE: ParkToken = ParkToken(ONE_READER | UPGRADABLE_BIT);
47
48pub struct RawRwLock<const RECURSIVE: bool = false> {
54 state: AtomicUsize,
55}
56
57pub type RawRwLockRecursive = RawRwLock<true>;
59
60unsafe impl<const RECURSIVE: bool> lock_api::RawRwLock for RawRwLock<RECURSIVE> {
61 const INIT: Self = Self {
62 state: AtomicUsize::new(0),
63 };
64
65 type SharedGuard = crate::GuardMarker;
66 type ExclusiveGuard = crate::GuardMarker;
67
68 #[inline]
69 fn lock_exclusive(&self) -> Self::ExclusiveGuard {
70 if self
71 .state
72 .compare_exchange_weak(0, WRITER_BIT, Ordering::Acquire, Ordering::Relaxed)
73 .is_ok()
74 {
75 self.deadlock_acquire_all();
76 Self::ExclusiveGuard::new()
77 } else {
78 self.lock_exclusive_slow(None).unwrap()
79 }
80 }
81
82 #[inline]
83 fn try_lock_exclusive(&self) -> Option<Self::ExclusiveGuard> {
84 self.state
85 .compare_exchange(0, WRITER_BIT, Ordering::Acquire, Ordering::Relaxed)
86 .ok()?;
87 self.deadlock_acquire_all();
88 Some(Self::ExclusiveGuard::new())
89 }
90
91 #[inline]
92 unsafe fn unlock_exclusive(&self, _guard: Self::ExclusiveGuard) {
93 self.deadlock_release_all();
94 let state = self.state.fetch_sub(WRITER_BIT, Ordering::Release);
95 if state & PARKED_BIT != 0 {
96 self.unlock_exclusive_or_upgradable_slow();
97 }
98 }
99
100 #[inline]
101 fn lock_shared(&self) -> Self::SharedGuard {
102 let guard = self
103 .try_lock_shared_fast()
104 .unwrap_or_else(|| self.lock_shared_slow(None).unwrap());
105 self.deadlock_acquire_secondary();
106 guard
107 }
108
109 #[inline]
110 fn try_lock_shared(&self) -> Option<Self::SharedGuard> {
111 let guard = self
112 .try_lock_shared_fast()
113 .or_else(|| self.try_lock_shared_slow())?;
114 self.deadlock_acquire_secondary();
115 Some(guard)
116 }
117
118 #[inline]
119 unsafe fn unlock_shared(&self, _guard: Self::SharedGuard) {
120 self.deadlock_release_secondary();
121 let state = self.state.fetch_sub(ONE_READER, Ordering::Release);
122 if state & (READERS_MASK | WRITER_PARKED_BIT) == (ONE_READER | WRITER_PARKED_BIT) {
123 self.unlock_shared_slow();
124 }
125 }
126
127 #[inline]
128 fn is_locked(&self) -> bool {
129 let state = self.state.load(Ordering::Relaxed);
130 state & (WRITER_BIT | READERS_MASK) != 0
131 }
132
133 #[inline]
134 fn is_locked_exclusive(&self) -> bool {
135 let state = self.state.load(Ordering::Relaxed);
136 state & (WRITER_BIT | READERS_MASK) == WRITER_BIT
137 }
138}
139
140unsafe impl<const RECURSIVE: bool> lock_api::RawRwLockFair for RawRwLock<RECURSIVE> {
141 #[inline]
142 unsafe fn unlock_shared_fair(&self, guard: Self::SharedGuard) {
143 unsafe { self.unlock_shared(guard) };
145 }
146
147 #[inline]
148 unsafe fn unlock_exclusive_fair(&self, _guard: Self::ExclusiveGuard) {
149 self.deadlock_release_all();
150 if self
151 .state
152 .compare_exchange(WRITER_BIT, 0, Ordering::Release, Ordering::Relaxed)
153 .is_ok()
154 {
155 return;
156 }
157 self.unlock_exclusive_fair_slow();
158 }
159
160 #[inline]
161 unsafe fn bump_shared(&self, _guard: &mut Self::SharedGuard) {
162 let state = self.state.load(Ordering::Relaxed);
163 if state & WRITER_BIT != 0 && (!RECURSIVE || state & READERS_MASK == ONE_READER) {
164 unsafe { self.bump_shared_slow() };
165 }
166 }
167
168 #[inline]
169 unsafe fn bump_exclusive(&self, _guard: &mut Self::ExclusiveGuard) {
170 if self.state.load(Ordering::Relaxed) & PARKED_BIT != 0 {
171 self.bump_exclusive_slow();
172 }
173 }
174}
175
176unsafe impl<const RECURSIVE: bool> lock_api::RawRwLockDowngrade for RawRwLock<RECURSIVE> {
177 #[inline]
178 unsafe fn downgrade(&self, guard: Self::ExclusiveGuard) -> Self::SharedGuard {
179 self.deadlock_release_primary();
180 let state = self
181 .state
182 .fetch_add(ONE_READER - WRITER_BIT, Ordering::Release);
183
184 if state & PARKED_BIT != 0 {
186 self.downgrade_slow();
187 }
188 guard
189 }
190}
191
192unsafe impl<const RECURSIVE: bool> lock_api::RawRwLockTimed for RawRwLock<RECURSIVE> {
193 type Duration = Duration;
194 type Instant = Instant;
195
196 #[inline]
197 fn try_lock_shared_for(&self, timeout: Self::Duration) -> Option<Self::SharedGuard> {
198 let guard = self
199 .try_lock_shared_fast()
200 .or_else(|| self.lock_shared_slow(util::to_deadline(timeout)))?;
201 self.deadlock_acquire_secondary();
202 Some(guard)
203 }
204
205 #[inline]
206 fn try_lock_shared_until(&self, timeout: Self::Instant) -> Option<Self::SharedGuard> {
207 let guard = self
208 .try_lock_shared_fast()
209 .or_else(|| self.lock_shared_slow(Some(timeout)))?;
210 self.deadlock_acquire_secondary();
211 Some(guard)
212 }
213
214 #[inline]
215 fn try_lock_exclusive_for(&self, timeout: Duration) -> Option<Self::ExclusiveGuard> {
216 if self
217 .state
218 .compare_exchange_weak(0, WRITER_BIT, Ordering::Acquire, Ordering::Relaxed)
219 .is_ok()
220 {
221 self.deadlock_acquire_all();
222 Some(Self::ExclusiveGuard::new())
223 } else {
224 self.lock_exclusive_slow(util::to_deadline(timeout))
225 }
226 }
227
228 #[inline]
229 fn try_lock_exclusive_until(&self, timeout: Instant) -> Option<Self::ExclusiveGuard> {
230 if self
231 .state
232 .compare_exchange_weak(0, WRITER_BIT, Ordering::Acquire, Ordering::Relaxed)
233 .is_ok()
234 {
235 self.deadlock_acquire_all();
236 Some(Self::ExclusiveGuard::new())
237 } else {
238 self.lock_exclusive_slow(Some(timeout))
239 }
240 }
241}
242
243unsafe impl<const RECURSIVE: bool> lock_api::RawRwLockUpgrade for RawRwLock<RECURSIVE> {
244 type UpgradableGuard = crate::GuardMarker;
245 #[inline]
246 fn lock_upgradable(&self) -> Self::UpgradableGuard {
247 let guard = self
248 .try_lock_upgradable_fast()
249 .unwrap_or_else(|| self.lock_upgradable_slow(None).unwrap());
250 self.deadlock_acquire_all();
251 guard
252 }
253
254 #[inline]
255 fn try_lock_upgradable(&self) -> Option<Self::UpgradableGuard> {
256 let guard = self
257 .try_lock_upgradable_fast()
258 .or_else(|| self.try_lock_upgradable_slow())?;
259 self.deadlock_acquire_all();
260 Some(guard)
261 }
262
263 #[inline]
264 unsafe fn unlock_upgradable(&self, _guard: Self::UpgradableGuard) {
265 self.deadlock_release_all();
266 let state = self
267 .state
268 .fetch_sub(ONE_READER | UPGRADABLE_BIT, Ordering::Release);
269 if state & PARKED_BIT != 0 {
270 self.unlock_exclusive_or_upgradable_slow();
271 }
272 }
273
274 #[inline]
275 unsafe fn upgrade(&self, guard: Self::UpgradableGuard) -> Self::ExclusiveGuard {
276 self.deadlock_release_secondary();
278 let state = self.state.fetch_sub(
279 (ONE_READER | UPGRADABLE_BIT) - WRITER_BIT,
280 Ordering::Acquire,
281 );
282 if state & READERS_MASK != ONE_READER {
283 self.upgrade_slow(guard, None)
284 .unwrap_or_else(|_| ::core::panicking::unreachable_default_msg()unreachable!())
285 } else {
286 self.deadlock_acquire_secondary();
287 guard
288 }
289 }
290
291 #[inline]
292 unsafe fn try_upgrade(
293 &self,
294 guard: Self::UpgradableGuard,
295 ) -> Result<Self::ExclusiveGuard, Self::UpgradableGuard> {
296 if self
297 .state
298 .compare_exchange_weak(
299 ONE_READER | UPGRADABLE_BIT,
300 WRITER_BIT,
301 Ordering::Acquire,
302 Ordering::Relaxed,
303 )
304 .is_ok()
305 {
306 Ok(guard)
307 } else {
308 self.try_upgrade_slow(guard)
309 }
310 }
311}
312
313unsafe impl<const RECURSIVE: bool> lock_api::RawRwLockUpgradeFair for RawRwLock<RECURSIVE> {
314 #[inline]
315 unsafe fn unlock_upgradable_fair(&self, _guard: Self::UpgradableGuard) {
316 self.deadlock_release_all();
317 let state = self.state.load(Ordering::Relaxed);
318 #[allow(clippy::collapsible_if)]
319 if state & PARKED_BIT == 0 {
320 if self
321 .state
322 .compare_exchange_weak(
323 state,
324 state - (ONE_READER | UPGRADABLE_BIT),
325 Ordering::Release,
326 Ordering::Relaxed,
327 )
328 .is_ok()
329 {
330 return;
331 }
332 }
333 self.unlock_upgradable_fair_slow();
334 }
335
336 #[inline]
337 unsafe fn bump_upgradable(&self, _guard: &mut Self::UpgradableGuard) {
338 if self.state.load(Ordering::Relaxed) & PARKED_BIT != 0 {
339 self.bump_upgradable_slow();
340 }
341 }
342}
343
344unsafe impl<const RECURSIVE: bool> lock_api::RawRwLockUpgradeDowngrade for RawRwLock<RECURSIVE> {
345 #[inline]
346 unsafe fn downgrade_upgradable(&self, guard: Self::UpgradableGuard) -> Self::SharedGuard {
347 self.deadlock_release_primary();
348 let state = self.state.fetch_sub(UPGRADABLE_BIT, Ordering::Relaxed);
349
350 if state & PARKED_BIT != 0 {
352 self.downgrade_slow();
353 }
354 guard
355 }
356
357 #[inline]
358 unsafe fn downgrade_to_upgradable(&self, guard: Self::ExclusiveGuard) -> Self::UpgradableGuard {
359 let state = self.state.fetch_add(
360 (ONE_READER | UPGRADABLE_BIT) - WRITER_BIT,
361 Ordering::Release,
362 );
363
364 if state & PARKED_BIT != 0 {
366 self.downgrade_to_upgradable_slow();
367 }
368 guard
369 }
370}
371
372unsafe impl<const RECURSIVE: bool> lock_api::RawRwLockUpgradeTimed for RawRwLock<RECURSIVE> {
373 #[inline]
374 fn try_lock_upgradable_until(&self, timeout: Instant) -> Option<Self::UpgradableGuard> {
375 let guard = self
376 .try_lock_upgradable_fast()
377 .or_else(|| self.lock_upgradable_slow(Some(timeout)))?;
378 self.deadlock_acquire_all();
379 Some(guard)
380 }
381
382 #[inline]
383 fn try_lock_upgradable_for(&self, timeout: Duration) -> Option<Self::UpgradableGuard> {
384 let guard = self
385 .try_lock_upgradable_fast()
386 .or_else(|| self.lock_upgradable_slow(util::to_deadline(timeout)))?;
387 self.deadlock_acquire_all();
388 Some(guard)
389 }
390
391 #[inline]
392 unsafe fn try_upgrade_until(
393 &self,
394 guard: Self::UpgradableGuard,
395 timeout: Instant,
396 ) -> Result<Self::ExclusiveGuard, Self::UpgradableGuard> {
397 self.deadlock_release_secondary();
399 let state = self.state.fetch_sub(
400 (ONE_READER | UPGRADABLE_BIT) - WRITER_BIT,
401 Ordering::Acquire,
402 );
403 if state & READERS_MASK == ONE_READER {
404 self.deadlock_acquire_secondary();
405 Ok(guard)
406 } else {
407 self.upgrade_slow(guard, Some(timeout))
408 }
409 }
410
411 #[inline]
412 unsafe fn try_upgrade_for(
413 &self,
414 guard: Self::UpgradableGuard,
415 timeout: Duration,
416 ) -> Result<Self::ExclusiveGuard, Self::UpgradableGuard> {
417 self.deadlock_release_secondary();
419 let state = self.state.fetch_sub(
420 (ONE_READER | UPGRADABLE_BIT) - WRITER_BIT,
421 Ordering::Acquire,
422 );
423 if state & READERS_MASK == ONE_READER {
424 self.deadlock_acquire_secondary();
425 Ok(guard)
426 } else {
427 self.upgrade_slow(guard, util::to_deadline(timeout))
428 }
429 }
430}
431
432impl<const RECURSIVE: bool> RawRwLock<RECURSIVE> {
433 #[inline(always)]
434 fn try_lock_shared_fast(&self) -> Option<crate::GuardMarker> {
435 let state = self.state.load(Ordering::Relaxed);
436
437 if state & WRITER_BIT != 0 && (!RECURSIVE || state & READERS_MASK == 0) {
440 return None;
441 }
442
443 let new_state = state.checked_add(ONE_READER)?;
444 self.state
445 .compare_exchange_weak(state, new_state, Ordering::Acquire, Ordering::Relaxed)
446 .ok()?;
447 Some(crate::GuardMarker::new())
448 }
449
450 #[cold]
451 fn try_lock_shared_slow(&self) -> Option<crate::GuardMarker> {
452 self.state
453 .try_update(Ordering::Acquire, Ordering::Relaxed, |state| {
454 if state & WRITER_BIT != 0 && (!RECURSIVE || state & READERS_MASK == 0) {
455 None
456 } else {
457 Some(
458 state
459 .checked_add(ONE_READER)
460 .expect("RwLock reader count overflow"),
461 )
462 }
463 })
464 .ok()?;
465 Some(crate::GuardMarker::new())
466 }
467
468 #[inline(always)]
469 fn try_lock_upgradable_fast(&self) -> Option<crate::GuardMarker> {
470 let state = self.state.load(Ordering::Relaxed);
471
472 if state & (WRITER_BIT | UPGRADABLE_BIT) != 0 {
475 return None;
476 }
477
478 let new_state = state.checked_add(ONE_READER | UPGRADABLE_BIT)?;
479 self.state
480 .compare_exchange_weak(state, new_state, Ordering::Acquire, Ordering::Relaxed)
481 .ok()?;
482 Some(crate::GuardMarker::new())
483 }
484
485 #[cold]
486 fn try_lock_upgradable_slow(&self) -> Option<crate::GuardMarker> {
487 self.state
488 .try_update(Ordering::Acquire, Ordering::Relaxed, |state| {
489 if state & (WRITER_BIT | UPGRADABLE_BIT) != 0 {
491 None
492 } else {
493 Some(
494 state
495 .checked_add(ONE_READER | UPGRADABLE_BIT)
496 .expect("RwLock reader count overflow"),
497 )
498 }
499 })
500 .ok()?;
501 Some(crate::GuardMarker::new())
502 }
503
504 #[cold]
505 fn lock_exclusive_slow(&self, timeout: Option<Instant>) -> Option<crate::GuardMarker> {
506 let try_lock = |state: &mut usize| {
507 loop {
508 if *state & (WRITER_BIT | UPGRADABLE_BIT) != 0 {
509 return false;
510 }
511
512 match self.state.compare_exchange_weak(
514 *state,
515 *state | WRITER_BIT,
516 Ordering::Acquire,
517 Ordering::Relaxed,
518 ) {
519 Ok(_) => return true,
520 Err(x) => *state = x,
521 }
522 }
523 };
524
525 let timed_out = !self.lock_common(timeout, TOKEN_EXCLUSIVE, try_lock, |state| {
527 state & (WRITER_BIT | UPGRADABLE_BIT) != 0
528 });
529 if timed_out {
530 return None;
531 }
532
533 self.deadlock_acquire_primary();
536
537 if !self.wait_for_readers(timeout, 0) {
539 return None;
540 }
541 self.deadlock_acquire_secondary();
542 Some(crate::GuardMarker::new())
543 }
544
545 #[cold]
546 fn unlock_exclusive_or_upgradable_slow(&self) {
547 let callback = |_, result: UnparkResult| {
548 if !result.have_more_threads {
551 self.state.fetch_and(!PARKED_BIT, Ordering::Relaxed);
552 }
553 TOKEN_NORMAL
554 };
555 unsafe {
557 self.wake_parked_threads(0, callback);
558 }
559 }
560
561 #[cold]
562 fn unlock_exclusive_fair_slow(&self) {
563 let callback = |mut new_state, result: UnparkResult| {
565 if result.unparked_threads != 0 {
568 if result.have_more_threads {
569 new_state |= PARKED_BIT;
570 }
571 self.state.store(new_state, Ordering::Release);
572 TOKEN_HANDOFF
573 } else {
574 if result.have_more_threads {
576 self.state.store(PARKED_BIT, Ordering::Release);
577 } else {
578 self.state.store(0, Ordering::Release);
579 }
580 TOKEN_NORMAL
581 }
582 };
583 unsafe {
585 self.wake_parked_threads(0, callback);
586 }
587 }
588
589 #[cold]
590 fn lock_shared_slow(&self, timeout: Option<Instant>) -> Option<crate::GuardMarker> {
591 let try_lock = |state: &mut usize| {
592 let mut spinwait_shared = SpinWait::new();
593 loop {
594 if *state & WRITER_BIT != 0 && (!RECURSIVE || *state & READERS_MASK == 0) {
595 return false;
596 }
597
598 if self
599 .state
600 .compare_exchange_weak(
601 *state,
602 state
603 .checked_add(ONE_READER)
604 .expect("RwLock reader count overflow"),
605 Ordering::Acquire,
606 Ordering::Relaxed,
607 )
608 .is_ok()
609 {
610 return true;
611 }
612
613 spinwait_shared.spin_no_yield();
617 *state = self.state.load(Ordering::Relaxed);
618 }
619 };
620 self.lock_common(timeout, TOKEN_SHARED, try_lock, |state| {
621 state & WRITER_BIT != 0 && (!RECURSIVE || state & READERS_MASK == 0)
622 })
623 .then_some(crate::GuardMarker::new())
624 }
625
626 #[cold]
627 fn unlock_shared_slow(&self) {
628 let addr = core::ptr::from_ref(self).addr() + 1;
632 let callback = |_result: UnparkResult| {
633 self.state.fetch_and(!WRITER_PARKED_BIT, Ordering::Relaxed);
636 TOKEN_NORMAL
637 };
638 unsafe {
642 parking_lot_core::unpark_one(addr, callback);
643 }
644 }
645
646 #[cold]
647 fn lock_upgradable_slow(&self, timeout: Option<Instant>) -> Option<crate::GuardMarker> {
648 let try_lock = |state: &mut usize| {
649 let mut spinwait_shared = SpinWait::new();
650 loop {
651 if *state & (WRITER_BIT | UPGRADABLE_BIT) != 0 {
652 return false;
653 }
654
655 if self
656 .state
657 .compare_exchange_weak(
658 *state,
659 state
660 .checked_add(ONE_READER | UPGRADABLE_BIT)
661 .expect("RwLock reader count overflow"),
662 Ordering::Acquire,
663 Ordering::Relaxed,
664 )
665 .is_ok()
666 {
667 return true;
668 }
669
670 spinwait_shared.spin_no_yield();
674 *state = self.state.load(Ordering::Relaxed);
675 }
676 };
677 self.lock_common(timeout, TOKEN_UPGRADABLE, try_lock, |state| {
678 state & (WRITER_BIT | UPGRADABLE_BIT) != 0
679 })
680 .then_some(crate::GuardMarker::new())
681 }
682
683 #[cold]
684 fn unlock_upgradable_fair_slow(&self) {
685 let mut state = self.state.load(Ordering::Relaxed);
687 while state & PARKED_BIT == 0 {
688 match self.state.compare_exchange_weak(
689 state,
690 state - (ONE_READER | UPGRADABLE_BIT),
691 Ordering::Release,
692 Ordering::Relaxed,
693 ) {
694 Ok(_) => return,
695 Err(x) => state = x,
696 }
697 }
698
699 let callback = |new_state, result: UnparkResult| {
701 let mut state = self.state.load(Ordering::Relaxed);
704 while let Some(mut new_state) =
707 (state - (ONE_READER | UPGRADABLE_BIT)).checked_add(new_state)
708 {
709 if result.have_more_threads {
710 new_state |= PARKED_BIT;
711 } else {
712 new_state &= !PARKED_BIT;
713 }
714 match self.state.compare_exchange_weak(
715 state,
716 new_state,
717 Ordering::Release,
718 Ordering::Relaxed,
719 ) {
720 Ok(_) => return TOKEN_HANDOFF,
721 Err(x) => state = x,
722 }
723 }
724
725 loop {
727 let mut new_state = state - (ONE_READER | UPGRADABLE_BIT);
728 if result.have_more_threads {
729 new_state |= PARKED_BIT;
730 } else {
731 new_state &= !PARKED_BIT;
732 }
733 match self.state.compare_exchange_weak(
734 state,
735 new_state,
736 Ordering::Release,
737 Ordering::Relaxed,
738 ) {
739 Ok(_) => return TOKEN_NORMAL,
740 Err(x) => state = x,
741 }
742 }
743 };
744 unsafe {
746 self.wake_parked_threads(0, callback);
747 }
748 }
749
750 #[cold]
751 fn try_upgrade_slow(
752 &self,
753 guard: crate::GuardMarker,
754 ) -> Result<crate::GuardMarker, crate::GuardMarker> {
755 match self
756 .state
757 .try_update(Ordering::Acquire, Ordering::Relaxed, |state| {
758 (state & READERS_MASK == ONE_READER)
759 .then_some(state - (ONE_READER | UPGRADABLE_BIT) + WRITER_BIT)
760 }) {
761 Ok(_) => Ok(guard),
762 Err(_) => Err(guard),
763 }
764 }
765
766 #[cold]
767 fn upgrade_slow(
768 &self,
769 guard: crate::GuardMarker,
770 timeout: Option<Instant>,
771 ) -> Result<crate::GuardMarker, crate::GuardMarker> {
772 let result = self.wait_for_readers(timeout, ONE_READER | UPGRADABLE_BIT);
773 self.deadlock_acquire_secondary();
776 if result { Ok(guard) } else { Err(guard) }
777 }
778
779 #[cold]
780 fn downgrade_slow(&self) {
781 let callback = |_, result: UnparkResult| {
783 if !result.have_more_threads {
785 self.state.fetch_and(!PARKED_BIT, Ordering::Relaxed);
786 }
787 TOKEN_NORMAL
788 };
789 unsafe {
791 self.wake_parked_threads(ONE_READER, callback);
792 }
793 }
794
795 #[cold]
796 fn downgrade_to_upgradable_slow(&self) {
797 let callback = |_, result: UnparkResult| {
799 if !result.have_more_threads {
801 self.state.fetch_and(!PARKED_BIT, Ordering::Relaxed);
802 }
803 TOKEN_NORMAL
804 };
805 unsafe {
807 self.wake_parked_threads(ONE_READER | UPGRADABLE_BIT, callback);
808 }
809 }
810
811 #[cold]
812 unsafe fn bump_shared_slow(&self) {
813 unsafe { self.unlock_shared(crate::GuardMarker::new()) };
814 util::abort_on_panic(|| self.lock_shared());
815 }
816
817 #[cold]
818 fn bump_exclusive_slow(&self) {
819 self.deadlock_release_all();
820 self.unlock_exclusive_fair_slow();
821 self.lock_exclusive();
822 }
823
824 #[cold]
825 fn bump_upgradable_slow(&self) {
826 self.deadlock_release_all();
827 self.unlock_upgradable_fair_slow();
828 util::abort_on_panic(|| self.lock_upgradable());
829 }
830
831 #[inline]
840 unsafe fn wake_parked_threads(
841 &self,
842 new_state: usize,
843 callback: impl FnOnce(usize, UnparkResult) -> UnparkToken,
844 ) {
845 let new_state = Cell::new(new_state);
849 let addr = core::ptr::from_ref(self).addr();
850 let filter = |ParkToken(token)| {
851 let s = new_state.get();
852
853 if !RECURSIVE && s & WRITER_BIT != 0 {
857 return FilterOp::Stop;
858 }
859
860 if token & (UPGRADABLE_BIT | WRITER_BIT) != 0 && s & (UPGRADABLE_BIT | WRITER_BIT) != 0
862 {
863 FilterOp::Skip
866 } else {
867 new_state.set(s + token);
868 FilterOp::Unpark
869 }
870 };
871 let callback = |result| callback(new_state.get(), result);
872 unsafe { parking_lot_core::unpark_filter(addr, filter, callback) };
877 }
878
879 #[inline]
882 fn wait_for_readers(&self, timeout: Option<Instant>, prev_value: usize) -> bool {
883 let mut spinwait = SpinWait::new();
886 let mut state = self.state.load(Ordering::Acquire);
887 while state & READERS_MASK != 0 {
888 if spinwait.spin() {
890 state = self.state.load(Ordering::Acquire);
891 continue;
892 }
893
894 if state & WRITER_PARKED_BIT == 0
896 && let Err(x) = self.state.compare_exchange_weak(
897 state,
898 state | WRITER_PARKED_BIT,
899 Ordering::Acquire,
900 Ordering::Acquire,
901 )
902 {
903 state = x;
904 continue;
905 }
906
907 let addr = core::ptr::from_ref(self).addr() + 1;
910 let validate = || {
911 let state = self.state.load(Ordering::Relaxed);
912 state & READERS_MASK != 0 && state & WRITER_PARKED_BIT != 0
913 };
914 let before_sleep = || {};
915 let timed_out = |_, was_last_thread: bool| {
916 if true {
if !was_last_thread {
::core::panicking::panic("assertion failed: was_last_thread")
};
};debug_assert!(was_last_thread);
919 self.state.fetch_and(!WRITER_PARKED_BIT, Ordering::Relaxed);
920 };
921 let park_result = unsafe {
926 parking_lot_core::park(
927 addr,
928 validate,
929 before_sleep,
930 timed_out,
931 TOKEN_EXCLUSIVE,
932 timeout,
933 )
934 };
935 match park_result {
936 ParkResult::Unparked(_) | ParkResult::Invalid => {
940 state = self.state.load(Ordering::Acquire);
941 continue;
942 }
943
944 ParkResult::TimedOut => {
946 if prev_value == 0 {
950 self.deadlock_release_primary();
954 }
955 let state = self
956 .state
957 .fetch_add(prev_value.wrapping_sub(WRITER_BIT), Ordering::Relaxed);
958 if state & PARKED_BIT != 0 {
959 let callback = |_, result: UnparkResult| {
960 if !result.have_more_threads {
962 self.state.fetch_and(!PARKED_BIT, Ordering::Relaxed);
963 }
964 TOKEN_NORMAL
965 };
966 unsafe {
968 self.wake_parked_threads(prev_value, callback);
969 }
970 }
971 return false;
972 }
973 }
974 }
975 true
976 }
977
978 #[inline]
980 fn lock_common(
981 &self,
982 timeout: Option<Instant>,
983 token: ParkToken,
984 mut try_lock: impl FnMut(&mut usize) -> bool,
985 should_park: impl Fn(usize) -> bool,
986 ) -> bool {
987 let mut spinwait = SpinWait::new();
988 let mut state = self.state.load(Ordering::Relaxed);
989 loop {
990 if try_lock(&mut state) {
992 return true;
993 }
994
995 if state & (PARKED_BIT | WRITER_PARKED_BIT) == 0 && spinwait.spin() {
997 state = self.state.load(Ordering::Relaxed);
998 continue;
999 }
1000
1001 if state & PARKED_BIT == 0
1003 && let Err(x) = self.state.compare_exchange_weak(
1004 state,
1005 state | PARKED_BIT,
1006 Ordering::Relaxed,
1007 Ordering::Relaxed,
1008 )
1009 {
1010 state = x;
1011 continue;
1012 }
1013
1014 let addr = core::ptr::from_ref(self).addr();
1016 let validate = || {
1017 let state = self.state.load(Ordering::Relaxed);
1018 state & PARKED_BIT != 0 && should_park(state)
1019 };
1020 let before_sleep = || {};
1021 let timed_out = |_, was_last_thread| {
1022 if was_last_thread {
1024 self.state.fetch_and(!PARKED_BIT, Ordering::Relaxed);
1025 }
1026 };
1027
1028 let park_result = unsafe {
1033 parking_lot_core::park(addr, validate, before_sleep, timed_out, token, timeout)
1034 };
1035 match park_result {
1036 ParkResult::Unparked(TOKEN_HANDOFF) => return true,
1039
1040 ParkResult::Unparked(_) => (),
1042
1043 ParkResult::Invalid => (),
1045
1046 ParkResult::TimedOut => return false,
1048 }
1049
1050 spinwait.reset();
1052 state = self.state.load(Ordering::Relaxed);
1053 }
1054 }
1055
1056 #[inline]
1057 fn deadlock_acquire_primary(&self) {
1058 unsafe { deadlock::acquire_resource(core::ptr::from_ref(self).addr()) };
1059 }
1060
1061 #[inline]
1062 fn deadlock_release_primary(&self) {
1063 unsafe { deadlock::release_resource(core::ptr::from_ref(self).addr()) };
1064 }
1065
1066 #[inline]
1067 fn deadlock_acquire_secondary(&self) {
1068 unsafe { deadlock::acquire_resource(core::ptr::from_ref(self).addr() + 1) };
1069 }
1070
1071 #[inline]
1072 fn deadlock_release_secondary(&self) {
1073 unsafe { deadlock::release_resource(core::ptr::from_ref(self).addr() + 1) };
1074 }
1075
1076 #[inline]
1077 fn deadlock_acquire_all(&self) {
1078 self.deadlock_acquire_primary();
1079 self.deadlock_acquire_secondary();
1080 }
1081
1082 #[inline]
1083 fn deadlock_release_all(&self) {
1084 self.deadlock_release_primary();
1085 self.deadlock_release_secondary();
1086 }
1087
1088 #[cfg(test)]
1089 pub(crate) fn has_parked_threads(&self) -> bool {
1090 self.state.load(Ordering::Relaxed) & (PARKED_BIT | WRITER_PARKED_BIT) != 0
1091 }
1092}