1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#[cfg(feature = "loom")]
pub use self::with_loom::*;

#[cfg(not(feature = "loom"))]
pub use parking_lot::*;

#[cfg(feature = "loom")]
mod with_loom {
	use std::{
		fmt,
		ops::{Deref, DerefMut},
	};

	#[derive(Debug, Default)]
	pub struct Mutex<T>(loom::sync::Mutex<T>);

	impl<T> Mutex<T> {
		pub fn new(val: T) -> Self {
			Self(loom::sync::Mutex::new(val))
		}

		pub fn lock(&self) -> MutexGuard<T> {
			MutexGuard(Some(self.0.lock().unwrap()))
		}
	}

	#[derive(Debug)]
	pub struct MutexGuard<'a, T>(Option<loom::sync::MutexGuard<'a, T>>);

	impl<'a, T> Deref for MutexGuard<'a, T> {
		type Target = T;

		fn deref(&self) -> &T {
			self.0.as_ref().unwrap().deref()
		}
	}

	impl<'a, T> DerefMut for MutexGuard<'a, T> {
		fn deref_mut(&mut self) -> &mut T {
			self.0.as_mut().unwrap().deref_mut()
		}
	}

	impl<'a, T: fmt::Display> fmt::Display for MutexGuard<'a, T> {
		fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
			self.0.as_ref().unwrap().fmt(f)
		}
	}

	#[derive(Debug, Default)]
	pub struct Condvar(loom::sync::Condvar);

	impl Condvar {
		pub fn new() -> Self {
			Self(loom::sync::Condvar::new())
		}

		pub fn notify_one(&self) {
			self.0.notify_one();
		}

		pub fn notify_all(&self) {
			self.0.notify_all()
		}

		pub fn wait<T>(&self, mutex_guard: &mut MutexGuard<T>) {
			mutex_guard.0 = Some(self.0.wait(mutex_guard.0.take().unwrap()).unwrap())
		}
	}

	#[derive(Debug, Default)]
	pub struct RwLock<T>(loom::sync::RwLock<T>);

	impl<T> RwLock<T> {
		pub fn new(val: T) -> Self {
			Self(loom::sync::RwLock::new(val))
		}

		pub fn read(&self) -> RwLockReadGuard<T> {
			RwLockReadGuard(self.0.read().unwrap())
		}

		pub fn upgradable_read(&self) -> RwLockUpgradableReadGuard<T> {
			RwLockUpgradableReadGuard(self.0.write().unwrap())
		}

		pub fn write(&self) -> RwLockWriteGuard<T> {
			RwLockWriteGuard(self.0.write().unwrap())
		}
	}

	#[derive(Debug)]
	pub struct RwLockReadGuard<'a, T>(loom::sync::RwLockReadGuard<'a, T>);

	impl<'a, T> Deref for RwLockReadGuard<'a, T> {
		type Target = T;

		fn deref(&self) -> &T {
			self.0.deref()
		}
	}

	/// We use here a write gard and not a read gard to avoid an other thread "stealing" the write
	/// lock during upgrade.
	///
	/// Indeed, if we had used a read gard here, to get a write gard we would have to release the
	/// read gard first, allowing an other thread to grab a write gard at this time and change the
	/// protected value state.
	#[derive(Debug)]
	pub struct RwLockUpgradableReadGuard<'a, T>(loom::sync::RwLockWriteGuard<'a, T>);

	impl<'a, T> RwLockUpgradableReadGuard<'a, T> {
		pub fn upgrade(s: Self) -> RwLockWriteGuard<'a, T> {
			RwLockWriteGuard(s.0)
		}
	}

	impl<'a, T> Deref for RwLockUpgradableReadGuard<'a, T> {
		type Target = T;

		fn deref(&self) -> &T {
			self.0.deref()
		}
	}

	#[derive(Debug)]
	pub struct RwLockWriteGuard<'a, T>(loom::sync::RwLockWriteGuard<'a, T>);

	impl<'a, T> RwLockWriteGuard<'a, T> {
		pub fn downgrade_to_upgradable(s: Self) -> RwLockUpgradableReadGuard<'a, T> {
			RwLockUpgradableReadGuard(s.0)
		}
	}

	impl<'a, T> Deref for RwLockWriteGuard<'a, T> {
		type Target = T;

		fn deref(&self) -> &T {
			self.0.deref()
		}
	}

	impl<'a, T> DerefMut for RwLockWriteGuard<'a, T> {
		fn deref_mut(&mut self) -> &mut T {
			self.0.deref_mut()
		}
	}
}