- 论坛徽章:
- 0
|
回复 1# jakepain
Otherwise, the kernel control path failed in acquiring the spin lock, thus the macro must cycle until the spin lock is released by a kernel control path running on some other CPU. Invokes preempt_enable( ) to undo the increase of the preemption counter done in step 1. If kernel preemption was enabled before executing the spin_lock macro, another process can now replace this process while it waits for the spin lock.
你提的是这一段吧,这一段是说如果获取spin_lock失败,那就循环忙等。直到别的CPU上占用spin_lock的内核代码释放锁。
在这里,原文插述了一句:调用preempt_enable可以使抢占计数-1。如果在调用spin_lock之前调用了preempt_enable的话,那么即使你调用spin_lock,也会在spin_lock忙等的时候出现抢占的情况。
不知道中文版是怎么翻译的,英文版看的就挺蛋疼,作者遮遮掩掩的说的前言不搭后语的,只是想说明,抢占计数preempt_count这个玩意是可以随便操作的。我们知道,preempt_count这个值在thread_info中,如果大于0,那么就代表不能抢占,等于0就可以抢占。而preempt_disable的动作只是将这个count+1,对应的,enable的动作就是将这个count-1。
回到这段英文,作者的意思是,本来preempt_count的值就是0——可以抢占。你要是闲的无聊或者不小心,在spin_lock之前再调用了preempt_enable,那么preempt_count=-1了。这之后你再正常调用spin_lock,里面会有preempt_disable的动作,preempt_count又加上了1,现在preempt_count=0了。等于之前加的一句preempt_enable,和spin_lock里的preempt_disable抵消了。
你看,你本来的愿望是期望spin_lock能关抢占的,但是现在没关上,自然可以在你忙等锁的时候发生抢占了。也就是原文中说的“ If kernel preemption was enabled before executing the spin_lock macro, another process can now replace this process while it waits for the spin lock.”
不知道我罗哩罗嗦的有没有讲清。这里提一句,preempt_count和spin_lock的机制是不一样的。preempt_count是对这个值进行加1减1的操作;而spin_lock是拿lock的值不停的去和“0”比是否相等,若相等,那么就把“1”写入lock中,获得锁了;若不等,就跳回去再读lock的值去与“0”比较,一直循环下去。可以看出,spin_lock不是像preempt_count那样加减的。因此,很重要的一点,同一个spin_lock不能像preempt_enable/disable操作那样嵌套。因为preempt_count加加减减又不会死,但是同一个spin_lock一旦嵌套了,外层的lock已经获得了,lock=1。而内层的lock还会傻乎乎的痴心的等待lock=0的那一天。。。。 |
|