2012-10-07 69 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,並且可能永遠不會成爲,因爲它們旨在成爲高性能鎖。

因此,如果條件爲真,發佈的代碼將會死鎖。