spinlock.rs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #![allow(dead_code)]
  2. use core::ptr::read_volatile;
  3. use core::sync::atomic::{AtomicBool, Ordering};
  4. use crate::arch::asm::irqflags::{local_irq_restore, local_irq_save};
  5. use crate::arch::interrupt::{cli, sti};
  6. use crate::include::bindings::bindings::{spin_lock, spin_unlock, spinlock_t};
  7. use crate::process::preempt::{preempt_disable, preempt_enable};
  8. /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁
  9. #[inline]
  10. pub fn spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut u64) {
  11. local_irq_save(flags);
  12. unsafe {
  13. spin_lock(lock);
  14. }
  15. }
  16. /// @brief 恢复rflags以及中断状态并解锁自旋锁
  17. #[inline]
  18. pub fn spin_unlock_irqrestore(lock: *mut spinlock_t, flags: &u64) {
  19. unsafe {
  20. spin_unlock(lock);
  21. }
  22. // kdebug!("123");
  23. local_irq_restore(flags);
  24. }
  25. /// 判断一个自旋锁是否已经被加锁
  26. #[inline]
  27. pub fn spin_is_locked(lock: &spinlock_t) -> bool {
  28. let val = unsafe { read_volatile(&lock.lock as *const i8) };
  29. return if val == 0 { true } else { false };
  30. }
  31. impl Default for spinlock_t {
  32. fn default() -> Self {
  33. Self { lock: 1 }
  34. }
  35. }
  36. /// @brief 关闭中断并加锁
  37. pub fn spin_lock_irq(lock: *mut spinlock_t) {
  38. cli();
  39. unsafe {
  40. spin_lock(lock);
  41. }
  42. }
  43. /// @brief 解锁并开中断
  44. pub fn spin_unlock_irq(lock: *mut spinlock_t) {
  45. unsafe {
  46. spin_unlock(lock);
  47. }
  48. sti();
  49. }
  50. /// 原始的Spinlock(自旋锁)
  51. /// 请注意,这个自旋锁和C的不兼容。
  52. ///
  53. /// @param self.0 这个AtomicBool的值为false时,表示没有被加锁。当它为true时,表示自旋锁已经被上锁。
  54. #[derive(Debug)]
  55. pub struct RawSpinlock(AtomicBool);
  56. impl RawSpinlock {
  57. /// @brief 初始化自旋锁
  58. pub const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false));
  59. /// @brief 加锁
  60. pub fn lock(&mut self) {
  61. while !self.try_lock() {}
  62. }
  63. /// @brief 关中断并加锁
  64. pub fn lock_irq(&mut self){
  65. cli();
  66. self.lock();
  67. }
  68. /// @brief 尝试加锁
  69. /// @return 加锁成功->true
  70. /// 加锁失败->false
  71. pub fn try_lock(&mut self) -> bool {
  72. // 先增加自旋锁持有计数
  73. preempt_disable();
  74. let res = self
  75. .0
  76. .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
  77. .is_ok();
  78. // 如果加锁失败恢复自旋锁持有计数
  79. if res == false {
  80. preempt_enable();
  81. }
  82. return res;
  83. }
  84. /// @brief 解锁
  85. pub fn unlock(&mut self){
  86. // 减少自旋锁持有计数
  87. preempt_enable();
  88. self.0.store(false, Ordering::Release);
  89. }
  90. /// @brief 放锁并开中断
  91. pub fn unlock_irq(&mut self){
  92. self.unlock();
  93. sti();
  94. }
  95. /// @brief 判断自旋锁是否被上锁
  96. ///
  97. /// @return true 自旋锁被上锁
  98. /// @return false 自旋锁处于解锁状态
  99. pub fn is_locked(&self)->bool
  100. {
  101. return self.0.load(Ordering::Relaxed).into();
  102. }
  103. /// @brief 强制设置自旋锁的状态
  104. /// 请注意,这样操作可能会带来未知的风险。因此它是unsafe的。(尽管从Rust语言本身来说,它是safe的)
  105. pub unsafe fn set_value(&mut self, value:bool){
  106. self.0.store(value, Ordering::SeqCst);
  107. }
  108. // todo: spin_lock_irqsave
  109. // todo: spin_unlock_irqrestore
  110. }