xref: /DragonOS/kernel/src/libs/spinlock.rs (revision 7cc4a02c7ff7bafd798b185beb7b0c2986b9f32f)
1 #![allow(dead_code)]
2 use core::cell::UnsafeCell;
3 use core::ops::{Deref, DerefMut};
4 use core::ptr::read_volatile;
5 
6 use core::sync::atomic::{AtomicBool, Ordering};
7 
8 use crate::arch::asm::irqflags::{local_irq_restore, local_irq_save};
9 use crate::arch::interrupt::{cli, sti};
10 use crate::include::bindings::bindings::{spin_lock, spin_unlock, spinlock_t};
11 use crate::process::preempt::{preempt_disable, preempt_enable};
12 use crate::syscall::SystemError;
13 
14 /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁
15 #[inline]
16 pub fn spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut usize) {
17     *flags = local_irq_save();
18     unsafe {
19         spin_lock(lock);
20     }
21 }
22 
23 /// @brief 恢复rflags以及中断状态并解锁自旋锁
24 #[inline]
25 pub fn spin_unlock_irqrestore(lock: *mut spinlock_t, flags: usize) {
26     unsafe {
27         spin_unlock(lock);
28     }
29     local_irq_restore(flags);
30 }
31 
32 /// 判断一个自旋锁是否已经被加锁
33 #[inline]
34 pub fn spin_is_locked(lock: &spinlock_t) -> bool {
35     let val = unsafe { read_volatile(&lock.lock as *const i8) };
36 
37     return if val == 0 { true } else { false };
38 }
39 
40 impl Default for spinlock_t {
41     fn default() -> Self {
42         Self { lock: 1 }
43     }
44 }
45 
46 /// @brief 关闭中断并加锁
47 pub fn spin_lock_irq(lock: *mut spinlock_t) {
48     cli();
49     unsafe {
50         spin_lock(lock);
51     }
52 }
53 
54 /// @brief 解锁并开中断
55 pub fn spin_unlock_irq(lock: *mut spinlock_t) {
56     unsafe {
57         spin_unlock(lock);
58     }
59     sti();
60 }
61 
62 /// 原始的Spinlock(自旋锁)
63 /// 请注意,这个自旋锁和C的不兼容。
64 ///
65 /// @param self.0 这个AtomicBool的值为false时,表示没有被加锁。当它为true时,表示自旋锁已经被上锁。
66 #[derive(Debug)]
67 pub struct RawSpinlock(AtomicBool);
68 
69 impl RawSpinlock {
70     /// @brief 初始化自旋锁
71     pub const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false));
72 
73     /// @brief 加锁
74     pub fn lock(&self) {
75         while !self.try_lock() {}
76     }
77 
78     /// @brief 关中断并加锁
79     pub fn lock_irq(&self) {
80         cli();
81         self.lock();
82     }
83 
84     /// @brief 尝试加锁
85     /// @return 加锁成功->true
86     ///         加锁失败->false
87     pub fn try_lock(&self) -> bool {
88         // 先增加自旋锁持有计数
89         preempt_disable();
90 
91         let res = self
92             .0
93             .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
94             .is_ok();
95 
96         // 如果加锁失败恢复自旋锁持有计数
97         if res == false {
98             preempt_enable();
99         }
100         return res;
101     }
102 
103     /// @brief 解锁
104     pub fn unlock(&self) {
105         // 减少自旋锁持有计数
106         preempt_enable();
107         self.0.store(false, Ordering::Release);
108     }
109 
110     /// @brief 放锁并开中断
111     pub fn unlock_irq(&self) {
112         self.unlock();
113         sti();
114     }
115 
116     /// @brief 判断自旋锁是否被上锁
117     ///
118     /// @return true 自旋锁被上锁
119     /// @return false 自旋锁处于解锁状态
120     pub fn is_locked(&self) -> bool {
121         return self.0.load(Ordering::Relaxed).into();
122     }
123 
124     /// @brief 强制设置自旋锁的状态
125     /// 请注意,这样操作可能会带来未知的风险。因此它是unsafe的。(尽管从Rust语言本身来说,它是safe的)
126     pub unsafe fn set_value(&mut self, value: bool) {
127         self.0.store(value, Ordering::SeqCst);
128     }
129 
130     /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁
131     pub fn lock_irqsave(&self, flags: &mut usize) {
132         *flags = local_irq_save();
133         self.lock();
134     }
135 
136     /// @brief 恢复rflags以及中断状态并解锁自旋锁
137     pub fn unlock_irqrestore(&self, flags: usize) {
138         self.unlock();
139         local_irq_restore(flags);
140     }
141 
142     /// @brief 尝试保存中断状态到flags中,关闭中断,并对自旋锁加锁
143     /// @return 加锁成功->true
144     ///         加锁失败->false
145     #[inline(always)]
146     pub fn try_lock_irqsave(&self, flags: &mut usize) -> bool {
147         *flags = local_irq_save();
148         if self.try_lock() {
149             return true;
150         }
151         local_irq_restore(*flags);
152         return false;
153     }
154 }
155 /// 实现了守卫的SpinLock, 能够支持内部可变性
156 ///
157 #[derive(Debug)]
158 pub struct SpinLock<T> {
159     lock: RawSpinlock,
160     /// 自旋锁保护的数据
161     data: UnsafeCell<T>,
162 }
163 
164 /// SpinLock的守卫
165 /// 该守卫没有构造器,并且其信息均为私有的。我们只能通过SpinLock的lock()方法获得一个守卫。
166 /// 因此我们可以认为,只要能够获得一个守卫,那么数据就在自旋锁的保护之下。
167 #[derive(Debug)]
168 pub struct SpinLockGuard<'a, T: 'a> {
169     lock: &'a SpinLock<T>,
170     flag: usize,
171 }
172 
173 /// 向编译器保证,SpinLock在线程之间是安全的.
174 /// 其中要求类型T实现了Send这个Trait
175 unsafe impl<T> Sync for SpinLock<T> where T: Send {}
176 
177 impl<T> SpinLock<T> {
178     pub const fn new(value: T) -> Self {
179         return Self {
180             lock: RawSpinlock::INIT,
181             data: UnsafeCell::new(value),
182         };
183     }
184 
185     #[inline(always)]
186     pub fn lock(&self) -> SpinLockGuard<T> {
187         self.lock.lock();
188         // 加锁成功,返回一个守卫
189         return SpinLockGuard {
190             lock: self,
191             flag: 0,
192         };
193     }
194 
195     pub fn lock_irqsave(&self) -> SpinLockGuard<T> {
196         let mut flags: usize = 0;
197 
198         self.lock.lock_irqsave(&mut flags);
199         // 加锁成功,返回一个守卫
200         return SpinLockGuard {
201             lock: self,
202             flag: flags,
203         };
204     }
205 
206     pub fn try_lock(&self) -> Result<SpinLockGuard<T>, SystemError> {
207         if self.lock.try_lock() {
208             return Ok(SpinLockGuard {
209                 lock: self,
210                 flag: 0,
211             });
212         }
213         return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
214     }
215 
216     pub fn try_lock_irqsave(&self) -> Result<SpinLockGuard<T>, SystemError> {
217         let mut flags: usize = 0;
218         if self.lock.try_lock_irqsave(&mut flags) {
219             return Ok(SpinLockGuard {
220                 lock: self,
221                 flag: flags,
222             });
223         }
224         return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
225     }
226 }
227 
228 /// 实现Deref trait,支持通过获取SpinLockGuard来获取临界区数据的不可变引用
229 impl<T> Deref for SpinLockGuard<'_, T> {
230     type Target = T;
231 
232     fn deref(&self) -> &Self::Target {
233         return unsafe { &*self.lock.data.get() };
234     }
235 }
236 
237 /// 实现DerefMut trait,支持通过获取SpinLockGuard来获取临界区数据的可变引用
238 impl<T> DerefMut for SpinLockGuard<'_, T> {
239     fn deref_mut(&mut self) -> &mut Self::Target {
240         return unsafe { &mut *self.lock.data.get() };
241     }
242 }
243 
244 /// @brief 为SpinLockGuard实现Drop方法,那么,一旦守卫的生命周期结束,就会自动释放自旋锁,避免了忘记放锁的情况
245 impl<T> Drop for SpinLockGuard<'_, T> {
246     fn drop(&mut self) {
247         if self.flag != 0 {
248             self.lock.lock.unlock_irqrestore(self.flag);
249         } else {
250             self.lock.lock.unlock();
251         }
252     }
253 }
254