12813126eSlogin /** 22813126eSlogin * @file spinlock.h 32813126eSlogin * @author fslongjin (longjin@RinGoTek.cn) 42813126eSlogin * @brief 自旋锁 52813126eSlogin * @version 0.1 62813126eSlogin * @date 2022-04-07 72813126eSlogin * 82813126eSlogin * @copyright Copyright (c) 2022 92813126eSlogin * 102813126eSlogin */ 112813126eSlogin #pragma once 12*cffd7144Slogin #include <asm/irqflags.h> 132813126eSlogin #include <common/glib.h> 142813126eSlogin #include <debug/bug.h> 152813126eSlogin 162813126eSlogin /** 172813126eSlogin * @brief 定义自旋锁结构体 182813126eSlogin * 192813126eSlogin */ 202813126eSlogin typedef struct 212813126eSlogin { 222813126eSlogin int8_t lock; // 1:unlocked 0:locked 232813126eSlogin } spinlock_t; 242813126eSlogin 25*cffd7144Slogin extern void __arch_spin_lock(spinlock_t *lock); 26*cffd7144Slogin extern void __arch_spin_unlock(spinlock_t *lock); 27*cffd7144Slogin 28*cffd7144Slogin extern void __arch_spin_lock_no_preempt(spinlock_t *lock); 29*cffd7144Slogin extern void __arch_spin_unlock_no_preempt(spinlock_t *lock); 30*cffd7144Slogin 31*cffd7144Slogin extern long __arch_spin_trylock(spinlock_t *lock); 32*cffd7144Slogin 332813126eSlogin /** 342813126eSlogin * @brief 自旋锁加锁 352813126eSlogin * 362813126eSlogin * @param lock 372813126eSlogin */ spin_lock(spinlock_t * lock)382813126eSloginvoid spin_lock(spinlock_t *lock) 392813126eSlogin { 40*cffd7144Slogin __arch_spin_lock(lock); 412813126eSlogin } 422813126eSlogin 432813126eSlogin /** 442813126eSlogin * @brief 自旋锁解锁 452813126eSlogin * 462813126eSlogin * @param lock 472813126eSlogin */ spin_unlock(spinlock_t * lock)482813126eSloginvoid spin_unlock(spinlock_t *lock) 492813126eSlogin { 50*cffd7144Slogin __arch_spin_unlock(lock); 512813126eSlogin } 522813126eSlogin 532813126eSlogin /** 542813126eSlogin * @brief 初始化自旋锁 552813126eSlogin * 562813126eSlogin * @param lock 572813126eSlogin */ spin_init(spinlock_t * lock)582813126eSloginvoid spin_init(spinlock_t *lock) 592813126eSlogin { 602813126eSlogin barrier(); 612813126eSlogin lock->lock = 1; 622813126eSlogin barrier(); 632813126eSlogin } 642813126eSlogin 652813126eSlogin /** 662813126eSlogin * @brief 自旋锁加锁(不改变自旋锁持有计数) 672813126eSlogin * 682813126eSlogin * @warning 慎用此函数,除非你有十足的把握不会产生自旋锁计数错误 692813126eSlogin */ spin_lock_no_preempt(spinlock_t * lock)702813126eSloginvoid spin_lock_no_preempt(spinlock_t *lock) 712813126eSlogin { 72*cffd7144Slogin __arch_spin_lock_no_preempt(lock); 732813126eSlogin } 74*cffd7144Slogin 752813126eSlogin /** 762813126eSlogin * @brief 自旋锁解锁(不改变自旋锁持有计数) 772813126eSlogin * 782813126eSlogin * @warning 慎用此函数,除非你有十足的把握不会产生自旋锁计数错误 792813126eSlogin */ spin_unlock_no_preempt(spinlock_t * lock)802813126eSloginvoid spin_unlock_no_preempt(spinlock_t *lock) 812813126eSlogin { 82*cffd7144Slogin __arch_spin_unlock_no_preempt(lock); 832813126eSlogin } 842813126eSlogin 852813126eSlogin /** 862813126eSlogin * @brief 尝试加锁 872813126eSlogin * 882813126eSlogin * @param lock 892813126eSlogin * @return long 锁变量的值(1为成功加锁,0为加锁失败) 902813126eSlogin */ spin_trylock(spinlock_t * lock)912813126eSloginlong spin_trylock(spinlock_t *lock) 922813126eSlogin { 93*cffd7144Slogin return __arch_spin_trylock(lock); 942813126eSlogin } 952813126eSlogin 962813126eSlogin /** 972813126eSlogin * @brief 保存中断状态,关闭中断,并自旋锁加锁 982813126eSlogin * 992813126eSlogin */ 1002813126eSlogin #define spin_lock_irqsave(lock, flags) \ 1012813126eSlogin do \ 1022813126eSlogin { \ 1032813126eSlogin local_irq_save(flags); \ 1042813126eSlogin spin_lock(lock); \ 1052813126eSlogin } while (0) 1062813126eSlogin 1072813126eSlogin /** 1082813126eSlogin * @brief 恢复rflags以及中断状态并解锁自旋锁 1092813126eSlogin * 1102813126eSlogin */ 1112813126eSlogin #define spin_unlock_irqrestore(lock, flags) \ 1122813126eSlogin do \ 1132813126eSlogin { \ 1142813126eSlogin spin_unlock(lock); \ 1152813126eSlogin local_irq_restore(flags); \ 1162813126eSlogin } while (0) 1172813126eSlogin 1182813126eSlogin /** 1192813126eSlogin * @brief 关闭中断并加锁 1202813126eSlogin * 1212813126eSlogin */ 1222813126eSlogin #define spin_lock_irq(lock) \ 1232813126eSlogin do \ 1242813126eSlogin { \ 1252813126eSlogin local_irq_disable(); \ 1262813126eSlogin spin_lock(lock); \ 1272813126eSlogin } while (0) 1282813126eSlogin 1292813126eSlogin /** 1302813126eSlogin * @brief 解锁并开启中断 1312813126eSlogin * 1322813126eSlogin */ 1332813126eSlogin #define spin_unlock_irq(lock) \ 1342813126eSlogin do \ 1352813126eSlogin { \ 1362813126eSlogin spin_unlock(lock); \ 1372813126eSlogin local_irq_enable(); \ 1382813126eSlogin } while (0) 1392813126eSlogin 1402813126eSlogin /** 1412813126eSlogin * @brief 判断自旋锁是否已经加锁 1422813126eSlogin * 1432813126eSlogin * @param lock 待判断的自旋锁 1442813126eSlogin * @return true 已经加锁 1452813126eSlogin * @return false 尚未加锁 1462813126eSlogin */ spin_is_locked(const spinlock_t * lock)1472813126eSloginstatic inline bool spin_is_locked(const spinlock_t *lock) 1482813126eSlogin { 1492813126eSlogin int x = READ_ONCE(lock->lock); 1502813126eSlogin return (x == 0) ? true : false; 1512813126eSlogin } 1522813126eSlogin 1532813126eSlogin #define assert_spin_locked(lock) BUG_ON(!spin_is_locked(lock))