- 论坛徽章:
- 1
|
与UP和SMP无关的定义:
typedef struct {
volatile unsigned int lock;
} spinlock_t;
#define SPIN_LOCK_UNLOCKED (spinlock_t){ 0 }
#define local_irq_save(x) __asm__ __volatile__(\"pushfl ; popl %0 ;
cli\":\"=g\" (x): /* no input */ :\"memory\")
spin_lock()在UP和SMP的不同:
UP下:
#define spin_lock(x) (void)lock
#define spin_unlock(x) do {} while(0)
可见,spin_lock(x)和spin_unlock(x)在UP环境下什么都不做。
SMP下:
void spin_lock(spinlock_t *plock)的执行过程如下:如果plock->lock=1,说明已被锁住,则 CPU 就不能去使用它所保护的资料结构;如果plock->lock=1,说明已被锁住,则可以从spin_lock()传回,接下去使用它所保护的资料。
spin_lock_irqsave()在UP和SMP的不同:
#define spin_lock_irqsave(lock,flags)
do { local_irq_save(flags);
spin_lock(lock); } while (0)
可见在UP和SMP下,spin_lock_irqsave()的代码是一样的,但是由于“在UP和SMP下,spin_lock(lock)函数的实现不同”,导致了“在UP和SMP下,spin_lock_irqsave()函数的实现不同”。
local_irq_save(flags) 做的事就是将 CPU 的 flag 值先储存到 flags 变数里,然后将 CPU 的中断 diable 掉。这里将
CPU 的中断 disable 是指将执行这段 code 的 CPU,并不是指全部的 CPU。 也就是说它只会 disable local CPU 的中断。local_irq_save(flags)保证了本地cpu(执行这段code的cpu)不会打断临界区代码的执行;spin_lock()则保证了其他的cpu不会打断临界代码的执行。
举例:
spinlock t xxx lock = SPIN_LOCK_UNLOCKED;
unsigned long flags;
spin
lock irqsave (&xxx lock, flags)
...critical section...
spin unlock
irqrestore (&xxx lock, flags)
在UP下的实现:
spinlock_t xxx_lock = SPIN_LOCK_UNLOCKED;
unsigned long flags;
local_save_flags(flags);
... critical section ...
local_restore_flags(flags);
具体请查看:http://www.yuanma.org/data/2007/0123/article_2168.htm
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/73067/showart_2046163.html |
|