xref: /DragonOS/kernel/src/libs/rwlock.rs (revision 7c28051e8c601312d3d0fd7bcb71bc71450d10c0)
1 #![allow(dead_code)]
2 use core::{
3     cell::UnsafeCell,
4     hint::spin_loop,
5     mem::{self, ManuallyDrop},
6     ops::{Deref, DerefMut},
7     sync::atomic::{AtomicU32, Ordering},
8 };
9 
10 use system_error::SystemError;
11 
12 use crate::{
13     arch::CurrentIrqArch,
14     exception::{InterruptArch, IrqFlagsGuard},
15     process::ProcessManager,
16 };
17 
18 ///RwLock读写锁
19 /// @brief READER位占据从右往左数第三个比特位
20 const READER: u32 = 1 << 2;
21 
22 /// @brief UPGRADED位占据从右到左数第二个比特位
23 const UPGRADED: u32 = 1 << 1;
24 
25 /// @brief WRITER位占据最右边的比特位
26 const WRITER: u32 = 1;
27 
28 const READER_BIT: u32 = 2;
29 
30 /// @brief 读写锁的基本数据结构
31 /// @param lock 32位原子变量,最右边的两位从左到右分别是UPGRADED,WRITER (标志位)
32 ///             剩下的bit位存储READER数量(除了MSB)
33 ///             对于标志位,0代表无, 1代表有
34 ///             对于剩下的比特位表征READER的数量的多少
35 ///             lock的MSB必须为0,否则溢出
36 #[derive(Debug)]
37 pub struct RwLock<T> {
38     lock: AtomicU32,
39     data: UnsafeCell<T>,
40 }
41 
42 /// @brief  READER守卫的数据结构
43 /// @param lock 是对RwLock的lock属性值的只读引用
44 pub struct RwLockReadGuard<'a, T: 'a> {
45     data: *const T,
46     lock: &'a AtomicU32,
47     irq_guard: Option<IrqFlagsGuard>,
48 }
49 
50 /// @brief UPGRADED是介于READER和WRITER之间的一种锁,它可以升级为WRITER,
51 ///        UPGRADED守卫的数据结构,注册UPGRADED锁只需要查看UPGRADED和WRITER的比特位
52 ///        但是当UPGRADED守卫注册后,不允许有新的读者锁注册
53 /// @param inner    是对RwLock数据结构的只读引用
54 pub struct RwLockUpgradableGuard<'a, T: 'a> {
55     data: *const T,
56     inner: &'a RwLock<T>,
57     irq_guard: Option<IrqFlagsGuard>,
58 }
59 
60 /// @brief WRITER守卫的数据结构
61 /// @param data     RwLock的data的可变引用
62 /// @param inner    是对RwLock数据结构的只读引用
63 pub struct RwLockWriteGuard<'a, T: 'a> {
64     data: *mut T,
65     inner: &'a RwLock<T>,
66     irq_guard: Option<IrqFlagsGuard>,
67 }
68 
69 unsafe impl<T: Send> Send for RwLock<T> {}
70 unsafe impl<T: Send + Sync> Sync for RwLock<T> {}
71 
72 /// @brief RwLock的API
73 impl<T> RwLock<T> {
74     #[inline]
75     /// @brief  RwLock的初始化
new(data: T) -> Self76     pub const fn new(data: T) -> Self {
77         return RwLock {
78             lock: AtomicU32::new(0),
79             data: UnsafeCell::new(data),
80         };
81     }
82 
83     #[allow(dead_code)]
84     #[inline]
85     /// @brief 将读写锁的皮扒掉,返回内在的data,返回的是一个真身而非引用
into_inner(self) -> T86     pub fn into_inner(self) -> T {
87         let RwLock { data, .. } = self;
88         return data.into_inner();
89     }
90 
91     #[allow(dead_code)]
92     #[inline]
93     /// @brief 返回data的raw pointer,
94     /// unsafe
as_mut_ptr(&self) -> *mut T95     pub fn as_mut_ptr(&self) -> *mut T {
96         return self.data.get();
97     }
98 
99     #[allow(dead_code)]
100     #[inline]
101     /// @brief 获取实时的读者数并尝试加1,如果增加值成功则返回增加1后的读者数,否则panic
current_reader(&self) -> Result<u32, SystemError>102     fn current_reader(&self) -> Result<u32, SystemError> {
103         const MAX_READERS: u32 = u32::MAX >> READER_BIT >> 1; //右移3位
104 
105         let value = self.lock.fetch_add(READER, Ordering::Acquire);
106         //value二进制形式的MSB不能为1, 否则导致溢出
107 
108         if value > MAX_READERS << READER_BIT {
109             self.lock.fetch_sub(READER, Ordering::Release);
110             //panic!("Too many lock readers, cannot safely proceed");
111             return Err(SystemError::EOVERFLOW);
112         } else {
113             return Ok(value);
114         }
115     }
116 
117     #[allow(dead_code)]
118     #[inline]
119     /// @brief 尝试获取READER守卫
try_read(&self) -> Option<RwLockReadGuard<T>>120     pub fn try_read(&self) -> Option<RwLockReadGuard<T>> {
121         ProcessManager::preempt_disable();
122         let r = self.inner_try_read();
123         if r.is_none() {
124             ProcessManager::preempt_enable();
125         }
126         return r;
127     }
128 
inner_try_read(&self) -> Option<RwLockReadGuard<T>>129     fn inner_try_read(&self) -> Option<RwLockReadGuard<T>> {
130         let reader_value = self.current_reader();
131         //得到自增后的reader_value, 包括了尝试获得READER守卫的进程
132 
133         let value = if let Ok(rv) = reader_value {
134             rv
135         } else {
136             return None;
137         };
138 
139         //判断有没有writer和upgrader
140         //注意, 若upgrader存在,已经存在的读者继续占有锁,但新读者不允许获得锁
141         if value & (WRITER | UPGRADED) != 0 {
142             self.lock.fetch_sub(READER, Ordering::Release);
143             return None;
144         } else {
145             return Some(RwLockReadGuard {
146                 data: unsafe { &*self.data.get() },
147                 lock: &self.lock,
148                 irq_guard: None,
149             });
150         }
151     }
152 
153     #[allow(dead_code)]
154     #[inline]
155     /// @brief 获得READER的守卫
read(&self) -> RwLockReadGuard<T>156     pub fn read(&self) -> RwLockReadGuard<T> {
157         loop {
158             match self.try_read() {
159                 Some(guard) => return guard,
160                 None => spin_loop(),
161             }
162         } //忙等待
163     }
164 
165     /// 关中断并获取读者守卫
read_irqsave(&self) -> RwLockReadGuard<T>166     pub fn read_irqsave(&self) -> RwLockReadGuard<T> {
167         loop {
168             let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
169             match self.try_read() {
170                 Some(mut guard) => {
171                     guard.irq_guard = Some(irq_guard);
172                     return guard;
173                 }
174                 None => spin_loop(),
175             }
176         }
177     }
178 
179     /// 尝试关闭中断并获取读者守卫
try_read_irqsave(&self) -> Option<RwLockReadGuard<T>>180     pub fn try_read_irqsave(&self) -> Option<RwLockReadGuard<T>> {
181         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
182         if let Some(mut guard) = self.try_read() {
183             guard.irq_guard = Some(irq_guard);
184             return Some(guard);
185         } else {
186             return None;
187         }
188     }
189 
190     #[allow(dead_code)]
191     #[inline]
192     /// @brief 获取读者+UPGRADER的数量, 不能保证能否获得同步值
reader_count(&self) -> u32193     pub fn reader_count(&self) -> u32 {
194         let state = self.lock.load(Ordering::Relaxed);
195         return state / READER + (state & UPGRADED) / UPGRADED;
196     }
197 
198     #[allow(dead_code)]
199     #[inline]
200     /// @brief 获取写者数量,不能保证能否获得同步值
writer_count(&self) -> u32201     pub fn writer_count(&self) -> u32 {
202         return (self.lock.load(Ordering::Relaxed) & WRITER) / WRITER;
203     }
204 
205     #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
206     #[allow(dead_code)]
207     #[inline]
208     /// @brief 尝试获得WRITER守卫
try_write(&self) -> Option<RwLockWriteGuard<T>>209     pub fn try_write(&self) -> Option<RwLockWriteGuard<T>> {
210         ProcessManager::preempt_disable();
211         let r = self.inner_try_write();
212         if r.is_none() {
213             ProcessManager::preempt_enable();
214         }
215 
216         return r;
217     } //当架构为arm时,有些代码需要作出调整compare_exchange=>compare_exchange_weak
218 
219     #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
220     #[allow(dead_code)]
221     #[inline]
try_write_irqsave(&self) -> Option<RwLockWriteGuard<T>>222     pub fn try_write_irqsave(&self) -> Option<RwLockWriteGuard<T>> {
223         ProcessManager::preempt_disable();
224         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
225         let r = self.inner_try_write().map(|mut g| {
226             g.irq_guard = Some(irq_guard);
227             g
228         });
229         if r.is_none() {
230             ProcessManager::preempt_enable();
231         }
232 
233         return r;
234     }
235 
236     #[cfg(any(target_arch = "x86_64", target_arch = "riscv64"))]
237     #[allow(dead_code)]
inner_try_write(&self) -> Option<RwLockWriteGuard<T>>238     fn inner_try_write(&self) -> Option<RwLockWriteGuard<T>> {
239         let res: bool = self
240             .lock
241             .compare_exchange(0, WRITER, Ordering::Acquire, Ordering::Relaxed)
242             .is_ok();
243         //只有lock大小为0的时候能获得写者守卫
244         if res {
245             return Some(RwLockWriteGuard {
246                 data: unsafe { &mut *self.data.get() },
247                 inner: self,
248                 irq_guard: None,
249             });
250         } else {
251             return None;
252         }
253     }
254 
255     #[allow(dead_code)]
256     #[inline]
257     /// @brief 获得WRITER守卫
write(&self) -> RwLockWriteGuard<T>258     pub fn write(&self) -> RwLockWriteGuard<T> {
259         loop {
260             match self.try_write() {
261                 Some(guard) => return guard,
262                 None => spin_loop(),
263             }
264         }
265     }
266 
267     #[allow(dead_code)]
268     #[inline]
269     /// @brief 获取WRITER守卫并关中断
write_irqsave(&self) -> RwLockWriteGuard<T>270     pub fn write_irqsave(&self) -> RwLockWriteGuard<T> {
271         loop {
272             let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
273             match self.try_write() {
274                 Some(mut guard) => {
275                     guard.irq_guard = Some(irq_guard);
276                     return guard;
277                 }
278                 None => spin_loop(),
279             }
280         }
281     }
282 
283     #[allow(dead_code)]
284     #[inline]
285     /// @brief 尝试获得UPGRADER守卫
try_upgradeable_read(&self) -> Option<RwLockUpgradableGuard<T>>286     pub fn try_upgradeable_read(&self) -> Option<RwLockUpgradableGuard<T>> {
287         ProcessManager::preempt_disable();
288         let r = self.inner_try_upgradeable_read();
289         if r.is_none() {
290             ProcessManager::preempt_enable();
291         }
292 
293         return r;
294     }
295 
296     #[allow(dead_code)]
try_upgradeable_read_irqsave(&self) -> Option<RwLockUpgradableGuard<T>>297     pub fn try_upgradeable_read_irqsave(&self) -> Option<RwLockUpgradableGuard<T>> {
298         let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
299         ProcessManager::preempt_disable();
300         let mut r = self.inner_try_upgradeable_read();
301         if r.is_none() {
302             ProcessManager::preempt_enable();
303         } else {
304             r.as_mut().unwrap().irq_guard = Some(irq_guard);
305         }
306 
307         return r;
308     }
309 
inner_try_upgradeable_read(&self) -> Option<RwLockUpgradableGuard<T>>310     fn inner_try_upgradeable_read(&self) -> Option<RwLockUpgradableGuard<T>> {
311         // 获得UPGRADER守卫不需要查看读者位
312         // 如果获得读者锁失败,不需要撤回fetch_or的原子操作
313         if self.lock.fetch_or(UPGRADED, Ordering::Acquire) & (WRITER | UPGRADED) == 0 {
314             return Some(RwLockUpgradableGuard {
315                 inner: self,
316                 data: unsafe { &mut *self.data.get() },
317                 irq_guard: None,
318             });
319         } else {
320             return None;
321         }
322     }
323 
324     #[allow(dead_code)]
325     #[inline]
326     /// @brief 获得UPGRADER守卫
upgradeable_read(&self) -> RwLockUpgradableGuard<T>327     pub fn upgradeable_read(&self) -> RwLockUpgradableGuard<T> {
328         loop {
329             match self.try_upgradeable_read() {
330                 Some(guard) => return guard,
331                 None => spin_loop(),
332             }
333         }
334     }
335 
336     #[inline]
337     /// @brief 获得UPGRADER守卫
upgradeable_read_irqsave(&self) -> RwLockUpgradableGuard<T>338     pub fn upgradeable_read_irqsave(&self) -> RwLockUpgradableGuard<T> {
339         loop {
340             let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
341             match self.try_upgradeable_read() {
342                 Some(mut guard) => {
343                     guard.irq_guard = Some(irq_guard);
344                     return guard;
345                 }
346                 None => spin_loop(),
347             }
348         }
349     }
350 
351     #[allow(dead_code)]
352     #[inline]
353     //extremely unsafe behavior
354     /// @brief 强制减少READER数
force_read_decrement(&self)355     pub unsafe fn force_read_decrement(&self) {
356         debug_assert!(self.lock.load(Ordering::Relaxed) & !WRITER > 0);
357         self.lock.fetch_sub(READER, Ordering::Release);
358     }
359 
360     #[allow(dead_code)]
361     #[inline]
362     //extremely unsafe behavior
363     /// @brief 强制给WRITER解锁
force_write_unlock(&self)364     pub unsafe fn force_write_unlock(&self) {
365         debug_assert_eq!(self.lock.load(Ordering::Relaxed) & !(WRITER | UPGRADED), 0);
366         self.lock.fetch_and(!(WRITER | UPGRADED), Ordering::Release);
367     }
368 
369     #[allow(dead_code)]
get_mut(&mut self) -> &mut T370     pub unsafe fn get_mut(&mut self) -> &mut T {
371         unsafe { &mut *self.data.get() }
372     }
373 
374     #[allow(dead_code)]
force_get_ref(&self) -> &T375     pub unsafe fn force_get_ref(&self) -> &T {
376         unsafe { &*self.data.get() }
377     }
378 }
379 
380 impl<T: Default> Default for RwLock<T> {
default() -> Self381     fn default() -> Self {
382         Self::new(Default::default())
383     }
384 }
385 
386 /// @brief 由原有的值创建新的锁
387 impl<T> From<T> for RwLock<T> {
from(data: T) -> Self388     fn from(data: T) -> Self {
389         return Self::new(data);
390     }
391 }
392 
393 impl<'rwlock, T> RwLockReadGuard<'rwlock, T> {
394     /// @brief 释放守卫,获得保护的值的不可变引用
395     ///
396     /// ## Safety
397     ///
398     /// 由于这样做可能导致守卫在另一个线程中被释放,从而导致pcb的preempt count不正确,
399     /// 因此必须小心的手动维护好preempt count。
400     ///
401     /// 并且,leak还可能导致锁的状态不正确。因此请仔细考虑是否真的需要使用这个函数。
402     #[allow(dead_code)]
403     #[inline]
leak(this: Self) -> &'rwlock T404     pub unsafe fn leak(this: Self) -> &'rwlock T {
405         let this = ManuallyDrop::new(this);
406         return unsafe { &*this.data };
407     }
408 }
409 
410 impl<'rwlock, T> RwLockUpgradableGuard<'rwlock, T> {
411     #[allow(dead_code)]
412     #[inline]
413     /// @brief 尝试将UPGRADER守卫升级为WRITER守卫
try_upgrade(mut self) -> Result<RwLockWriteGuard<'rwlock, T>, Self>414     pub fn try_upgrade(mut self) -> Result<RwLockWriteGuard<'rwlock, T>, Self> {
415         let res = self.inner.lock.compare_exchange(
416             UPGRADED,
417             WRITER,
418             Ordering::Acquire,
419             Ordering::Relaxed,
420         );
421         //当且仅当只有UPGRADED守卫时可以升级
422 
423         if res.is_ok() {
424             let inner = self.inner;
425             let irq_guard = self.irq_guard.take();
426             mem::forget(self);
427 
428             Ok(RwLockWriteGuard {
429                 data: unsafe { &mut *inner.data.get() },
430                 inner,
431                 irq_guard,
432             })
433         } else {
434             Err(self)
435         }
436     }
437 
438     #[allow(dead_code)]
439     #[inline]
440     /// @brief 将upgrader升级成writer
upgrade(mut self) -> RwLockWriteGuard<'rwlock, T>441     pub fn upgrade(mut self) -> RwLockWriteGuard<'rwlock, T> {
442         loop {
443             self = match self.try_upgrade() {
444                 Ok(writeguard) => return writeguard,
445                 Err(former) => former,
446             };
447 
448             spin_loop();
449         }
450     }
451 
452     #[allow(dead_code)]
453     #[inline]
454     /// @brief UPGRADER降级为READER
downgrade(mut self) -> RwLockReadGuard<'rwlock, T>455     pub fn downgrade(mut self) -> RwLockReadGuard<'rwlock, T> {
456         while self.inner.current_reader().is_err() {
457             spin_loop();
458         }
459 
460         let inner: &RwLock<T> = self.inner;
461         let irq_guard = self.irq_guard.take();
462         // 自动移去UPGRADED比特位
463         mem::drop(self);
464 
465         RwLockReadGuard {
466             data: unsafe { &*inner.data.get() },
467             lock: &inner.lock,
468             irq_guard,
469         }
470     }
471 
472     #[allow(dead_code)]
473     #[inline]
474     /// @brief 返回内部数据的引用,消除守卫
475     ///
476     /// ## Safety
477     ///
478     /// 由于这样做可能导致守卫在另一个线程中被释放,从而导致pcb的preempt count不正确,
479     /// 因此必须小心的手动维护好preempt count。
480     ///
481     /// 并且,leak还可能导致锁的状态不正确。因此请仔细考虑是否真的需要使用这个函数。
leak(this: Self) -> &'rwlock T482     pub unsafe fn leak(this: Self) -> &'rwlock T {
483         let this: ManuallyDrop<RwLockUpgradableGuard<'_, T>> = ManuallyDrop::new(this);
484 
485         unsafe { &*this.data }
486     }
487 }
488 
489 impl<'rwlock, T> RwLockWriteGuard<'rwlock, T> {
490     #[allow(dead_code)]
491     #[inline]
492     /// @brief 返回内部数据的引用,消除守卫
493     ///
494     /// ## Safety
495     ///
496     /// 由于这样做可能导致守卫在另一个线程中被释放,从而导致pcb的preempt count不正确,
497     /// 因此必须小心的手动维护好preempt count。
498     ///
499     /// 并且,leak还可能导致锁的状态不正确。因此请仔细考虑是否真的需要使用这个函数。
leak(this: Self) -> &'rwlock T500     pub unsafe fn leak(this: Self) -> &'rwlock T {
501         let this = ManuallyDrop::new(this);
502 
503         return unsafe { &*this.data };
504     }
505 
506     #[allow(dead_code)]
507     #[inline]
508     /// @brief 将WRITER降级为READER
downgrade(mut self) -> RwLockReadGuard<'rwlock, T>509     pub fn downgrade(mut self) -> RwLockReadGuard<'rwlock, T> {
510         while self.inner.current_reader().is_err() {
511             spin_loop();
512         }
513         //本质上来说绝对保证没有任何读者
514 
515         let inner = self.inner;
516         let irq_guard = self.irq_guard.take();
517         mem::drop(self);
518 
519         return RwLockReadGuard {
520             data: unsafe { &*inner.data.get() },
521             lock: &inner.lock,
522             irq_guard,
523         };
524     }
525 
526     #[allow(dead_code)]
527     #[inline]
528     /// @brief 将WRITER降级为UPGRADER
downgrade_to_upgradeable(mut self) -> RwLockUpgradableGuard<'rwlock, T>529     pub fn downgrade_to_upgradeable(mut self) -> RwLockUpgradableGuard<'rwlock, T> {
530         debug_assert_eq!(
531             self.inner.lock.load(Ordering::Acquire) & (WRITER | UPGRADED),
532             WRITER
533         );
534 
535         self.inner.lock.store(UPGRADED, Ordering::Release);
536 
537         let inner = self.inner;
538 
539         let irq_guard = self.irq_guard.take();
540         mem::forget(self);
541 
542         return RwLockUpgradableGuard {
543             inner,
544             data: unsafe { &*inner.data.get() },
545             irq_guard,
546         };
547     }
548 }
549 
550 impl<T> Deref for RwLockReadGuard<'_, T> {
551     type Target = T;
552 
deref(&self) -> &Self::Target553     fn deref(&self) -> &Self::Target {
554         return unsafe { &*self.data };
555     }
556 }
557 
558 impl<T> Deref for RwLockUpgradableGuard<'_, T> {
559     type Target = T;
560 
deref(&self) -> &Self::Target561     fn deref(&self) -> &Self::Target {
562         return unsafe { &*self.data };
563     }
564 }
565 
566 impl<T> Deref for RwLockWriteGuard<'_, T> {
567     type Target = T;
568 
deref(&self) -> &Self::Target569     fn deref(&self) -> &Self::Target {
570         return unsafe { &*self.data };
571     }
572 }
573 
574 impl<T> DerefMut for RwLockWriteGuard<'_, T> {
deref_mut(&mut self) -> &mut Self::Target575     fn deref_mut(&mut self) -> &mut Self::Target {
576         return unsafe { &mut *self.data };
577     }
578 }
579 
580 impl<T> Drop for RwLockReadGuard<'_, T> {
drop(&mut self)581     fn drop(&mut self) {
582         debug_assert!(self.lock.load(Ordering::Relaxed) & !(WRITER | UPGRADED) > 0);
583         self.lock.fetch_sub(READER, Ordering::Release);
584         ProcessManager::preempt_enable();
585     }
586 }
587 
588 impl<T> Drop for RwLockUpgradableGuard<'_, T> {
drop(&mut self)589     fn drop(&mut self) {
590         debug_assert_eq!(
591             self.inner.lock.load(Ordering::Relaxed) & (WRITER | UPGRADED),
592             UPGRADED
593         );
594         self.inner.lock.fetch_sub(UPGRADED, Ordering::AcqRel);
595         ProcessManager::preempt_enable();
596         //这里为啥要AcqRel? Release应该就行了?
597     }
598 }
599 
600 impl<T> Drop for RwLockWriteGuard<'_, T> {
drop(&mut self)601     fn drop(&mut self) {
602         debug_assert_eq!(self.inner.lock.load(Ordering::Relaxed) & WRITER, WRITER);
603         self.inner
604             .lock
605             .fetch_and(!(WRITER | UPGRADED), Ordering::Release);
606         self.irq_guard.take();
607         ProcessManager::preempt_enable();
608     }
609 }
610