unsigned long flags;
spin lock irqsave (&xxx lock, flags)
...critical section...
spin unlock irqrestore (&xxx lock, flags)
在
local_irq_save(flags) 做的事就是将 CPU 的
flag 值先储存到 flags 变数里,然后将 CPU 的中断 diable 掉。这里将 CPU 的中断 disable 是指将执行这段 code 的
CPU,并不是指全部的 CPU。 也就是说他只会 disable local CPU 的中断。我们能够在
#define spin_lock_irqsave(lock,flags)
do while (0)
#define spin_unlock_irqrestore(lock,flags)
do while (0)
至于 local_irq_restore(flags)
从字面上能够很清楚的看出来,只是将 flags 里的值再设回 CPU 的 flag 里而已。至于 spin_lock(lock) 和
spin_unlock(lock) 这两个函式,在 SMP 和在 UP 的环境底下则会扩展成不同的样子。首先先看到
#define local_irq_save(x) __asm__ __volatile__("pushfl ; popl %0 ;
cli":"=g" (x): /* no input */ :"memory")
#define local_irq_restore(x) __asm__ __volatile__("pushl %0 ; popfl"
/* no output */ :"g" (x):"memory")
在 SMP 的环境底下,SMP 这个constant被会 set。而在
UP 底下则不会,所以,假如要看 UP 底下 spin_lock(lock) 会变成怎幺样子,就必须来看看 #else /* !SMP */ 和
#endif 之间的程式码。
#ifdef __SMP__
#include <asm/spinlock.h>
#else /* !SMP */
.......
#endif
UP 环境下的 Implementation
我们先来看看在 UP 的环境下, spin_lock(lock) 会变成什幺样子。
简单吧,根本什幺事都没有做,所以,在 UP
的环境底下,我们假如将上面那段 spinlock 的使用扩展开来的话,会变成下面这个样子。
#define spin_lock(x) (void)lock
#define spin_unlock(x) do {} while(0)
而这也正是在 UP
环境下,用来保护重要资料结构的写法。这也就是为什幺在介绍spinlock_t 的结构内容时,我们说在UP环境底下这个结构就算是空的也不会影响到 spinlock
的功效,因为根本没用到里面的栏位,但是在 SMP 底下,这就很重要了。
spinlock_t xxx_lock = SPIN_LOCK_UNLOCKED;
unsigned long flags;
local_save_flags(flags); cli();
... critical section ...
local_restore_flags(flags);
SMP 环境下的 Implementation
在 SMP 的环境底下, spin_lock() 和 spin_unlock() 这两个函式的源代码是放在
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!




