在Linux的内核中,spin lock用在多处理器环境中。当一个CPU访问一个临界资源
(critical section)的时候,需要预先取得spin lock,如果取不到的话,它就在空循环
等待,直到另外的CPU释放spin lock。由于涉及到多个处理器,spin lock的效率非常重要。
因为在等待spin lock的过程,处理器只是不停的循环检查,并不执行其他指令。但即使这样
,
一般来说,spn lock的开销还是比进程调度(context switch)少得多。这就是spin lock
被广泛应用在多处理器环境的原因。
1. spin lock的数据结构
/* include/asm-i386/spinlock.h */
typedef struct {
volatile unsigned int lock;
} spinlock_t;
spin lock的数据结构很简单,只是一个整数变量lock, 如果lock等于1的话,表示
这个spin lock是自由的;如果lock小于等于0的话,则表示spin lock已经被其他CPU所
获取。
2. spin lock的实现
#define spin_lock_string
"n1:t"
"lock ; decb %0nt"
"js 2fn"
".section .text.lock,"ax"n"
"2:t"
"cmpb $0,%0nt"
"rep;nopnt"
"jle 2bnt"
"jmp 1bn"
".previous"
#define spin_unlock_string
"movb $1,%0"
:"=m" (lock->lock) : : "memory"
static inline void spin_lock(spinlock_t *lock)
{
__asm__ __volatile__(
spin_lock_string
:"=m" (lock->lock) : : "memory");
}
static inline void spin_unlock(spinlock_t *lock)
{
char oldval = 1;
__asm__ __volatile__(
spin_unlock_string
);
}
如果将上面的语句转化成纯汇编的话,则是这样:
spin_lock(lock)
1:
lock ; decb %0
js 2f
.section .text.lock, "ax"
2: cmpb $0,%0
rep;nop
jle 2b
jmp 1b
.previous