2013-01-21 60 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的价值,在这种情况下这是不可能的。 –