2013-01-21 84 views
4

我有一個功能,我更新結構,並禁用中斷。這裏需要揮發嗎?

bool readBuffer() 
{ 
    __disable_irq(); 

    rb->reader += 1; // Just an example 

    __enable_irq(); 

    return true; 
} 

由於中斷被禁止,其不可能的另一箇中斷預搶佔而1M的結構更新的值。

但是,我是否也應該將讀取器變量標記爲volatile?由於理論上其他中斷可能在我輸入函數時搶先,但在實際調用__disable_irq()之前。當我的函數恢復時,緩存的值rb->reader將不正確。或者,編譯器(GCC)生成的代碼是否不緩存rb->reader直到該行實際被擊中?

+3

也許可以參考Linus Torvalds的[揮發性認爲有害](http://www.kernel.org/doc/Documentation/volatile-considered-harmful.txt)。 '__disable_irq()'是否作爲隱式內存屏障?如果是的話,那麼你不需要'易失性',並使用它只能傷害。 – Celada

回答

1

可能這將是更好地爲您指定明確的優化屏障:

bool readBuffer() 
{ 
    __disable_irq(); 
    asm volatile ("" ::: "memory"); // Some unexpected memory modification 
    rb->reader += 1; // Just an example 
    __enable_irq(); 
    return true; 
} 

如果在其他一些情況下,你希望編譯器優化rb->reader變量這將是有利可圖的,並且將其標記揮發會因此過度。

+0

你有什麼建議似乎是一個優化的障礙嗎?記憶障礙略有不同。也許你可以在asm部分加一個'lock'指令,例如'asm volatile(「lock; addl $ 0,0(%% esp)」:::「memory」)。 Joshua需要的是一個內存屏障,但是你所建議的似乎更像是一個優化屏障,暗示編譯器不要依賴來自'asm'之前由代碼段填充的寄存器的值。這並不能保證'rb-> reader + = 1'只會在__disable_irq()之後執行。 –

+0

我認爲,''volatile''也是最優化的障礙,而不是記憶之一。感謝您糾正我的術語,編輯後。但我想,這裏的優化障礙就足夠了,因爲約書亞更擔心優化rb-> reader的價值,在這種情況下這是不可能的。 –