咱們在開發中,經常會用到自旋鎖,對於使用接口來說。仿照樣例誰都會用,但是你知道其是怎樣實現自旋的嗎?今天咱們就來討論一下事實上現原理。函數
一、首先,咱們需要實現一個結構體用於自旋鎖的使用rest
typedef struct spinlock{接口
volatile unsigned int slock;開發
}spinlock_t;it
接下來咱們就要定義接口了;class
二、接口實現原理
(1)初始化接口static
#define spin_lock_init(lock) \di
do{ \while
((spinlock_t *)lock)->slock = 0x0; \ /*至關於賦初值*/
}while(0)
(2)上鎖接口
static inline void spin_lock(spinlock_t *lock)
{
raw_spin_lock(&lock->slock);
}
(3)釋放鎖
static inline spin_unlock(spinlock_t *lock)
{
raw_spin_unlock(&lock->slock);
}
三、更底層彙編實現
你們可以看到上邊上鎖和解鎖都調用了另外兩個函數。這兩個函數纔是自旋鎖的精華所在,下邊咱們來詳細討論一下
raw_spin_lock:
mov r1,#1 @1-->r1
DSB
take_again:
LDREX r2,[r0] @把r0的內容賦給r2,同一時候置全局標誌exclusive
STREX r3,r1,[r0] @嘗試將r1寫入到鎖裏邊,首先檢查exclusive是否存在,假設存在則將r1-->r0,r3 = 0。並清除exclusive標誌。不然1--->r3,結束
TEQ r3,#0
BNE take_again
TEQ r2,#0
BNE take_again
MOV pc,lr @返回
raw_spin_unlock:
DSB
MOV r1,#0
STR r1,[r0,#0] @爲0。標示鎖已釋放
DSB
MOV pc,lr
通過這兩段代碼,是否是對自旋鎖的實現更加清晰明瞭了?
四、假設想在自旋鎖的同一時候鎖中斷和開中斷怎麼辦呢?僅僅需要在獲取鎖和釋放鎖接口裏加上相似於local_irq_save和local_irq_restore之類的中斷控制函數就能夠