2012-10-07 70 views
1

我读了一些代码,我在函数foo看到:使用spin_lock和spin_lock_irqsave,死锁?

// x is a global variable shared by all functions 
spin_lock(&x); 
if(some condition) 
    function(); 
spin_unlock(&x); 

函数();

// do stuff 
spin_lock_irqsave(&x, vals); 
.... 

如果“某些条件”为真,会不会出现死锁?这似乎太明显了,所以我想也许我错过了什么?

感谢

编辑:该代码是不是Linux的一部分,它只是一些随机代码,我在网上找到

+2

它是什么代码,以避免它? – ninjalj

回答

0

这将取决于如何spin_lock()spin_lock_irqsave()已付诸实施。

例如,他们可能确定锁是否已被同一个CPU锁定,如果是,则增加一个计数器;然后(当锁被释放时)递减计数器并且只有当计数器变为零时才释放锁。那样的话,同一个CPU可以多次获取锁,并且不会导致死锁。

spin_lock_irqsave()也可能是只禁用IRQ,实际上并没有获取锁(例如假定/预期spin_lock()事先被调用过的东西)。在这种情况下,锁&x可能只是一个方便的地方来存储/跟踪IRQ被禁用的事实(并且可能spin_unlock()检查某些标志并在禁用时再次启用IRQ)。

但是,我想不出spin_lock_irqsave()需要第二个参数(vals)的原因。

另一种可能性是这些功能的名称具有误导性,与它们实际上的功能无关。例如; spin_lock()函数可能会订购比萨饼,spin_lock_irqsave()函数可能会显示足球结果。

基本上,除了名称之外,没有关于这些函数的信息,因此不可能确定它们的作用(或者如果存在或不存在死锁)。

+2

好的答案,除了'spin_lock'和'spin_lock_irqsave' [记录的Linux内核函数](http://www.makelinux.net/ldd3/chp-5-sect-5)。不需要猜测他们做了什么。 – nneonneo

+0

这个问题明确指出:“代码不是Linux的一部分,它只是一些我在网上找到的随机代码”。我认为'Linux'标签出错了。 – Brendan

+0

...然后标签是'linux','kernel'。我把它解释为“这不是Linux内核,它是随机的内核代码。” – nneonneo

1

这段代码会死锁(假设没有递归锁定,并且这是一些Linux内核代码)。通常当你想保护你的代码不被中断抢占时,使用spin_lock的irq版本。

vals的原因是保存当前的中断状态并在调用irqrestore时恢复它。这是为了避免如果抓取多个自旋锁或处于中断被禁用的块中,则提前中断。

1

旋转锁是not recursive,并且可能永远不会成为,因为它们旨在成为高性能锁。

因此,如果条件为真,发布的代码将会死锁。