为尊重原创,转载请注明出处。
我们在开发中,经常会用到自旋锁,对于使用接口来讲,仿照例子谁都会用,但是你知道其是如何实现自旋的吗?今天我们就来讨论一下其实现原理。
1、首先,我们需要实现一个结构体用于自旋锁的使用
typedef struct spinlock{
volatile unsigned int slock;
}spinlock_t;
好了,现在相当于我们有家伙了,接下来我们就要定义接口了;
2、接口实现
(1)初始化接口
#define spin_lock_init(lock) \
do{ \
((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);
}
3、更底层汇编实现
大家可以看到上边上锁和解锁都调用了另外两个函数,这两个函数才是自旋锁的精华所在,下边我们来具体讨论一下
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
经过这两段代码,是不是对自旋锁的实现更加清晰明了了?
4、如果想在自旋锁的同时锁中断和开中断怎么办呢?只需要在获取锁和释放锁接口里加上类似于local_irq_save和local_irq_restore之类的中断控制函数即可
你知道底层自旋锁是如何实现的吗,布布扣,bubuko.com
原文:http://blog.csdn.net/lixiaojie1012/article/details/24272757