中断的易失性与内存屏障
volatile vs memory barrier for interrupts
令x
和y
为主代码和中断代码共享的变量。
我对 volatile
的看法是,它只是而且总是需要用于主代码中也使用的硬件变量和中断变量。
通过禁用中断,保证主代码中 x
和 y
的每次使用都是原子的。
x
和 y
真的需要 volatile
,还是在使用它们强制从 RAM 重新加载变量之前设置内存屏障就足够了?
A)
volatile bool x;
volatile int y[100];
int main(void)
{
while (true) {
disable_interrupts();
if (x)
work(y);
x = false;
enable_interrupts();
}
}
B)
bool x;
int y[100];
int main(void)
{
while (true) {
memory_barrier();
disable_interrupts();
if (x)
work(y);
x = false;
enable_interrupts();
}
}
目标是:
让编译器优化work()
.
能够使用标准库函数,例如 memcpy()
(这些函数不能与 volatile
变量一起使用)。
编辑:添加中断示例
interrupts.c
:
extern volatile? int x;
extern volatile? int y;
void interrupt(void)
{
x = true;
REGY1 = y[7];
y[23] = REGY2;
}
内存屏障代替 volatile
就可以了。 Linux 内核开发人员 prefer it that way
有几点需要注意。
- 禁用中断后移动屏障。中断往往发生在最糟糕的时候。
- 在启用中断之前,您需要第二个内存屏障,用于在主程序中写入并在中断处理程序中读取的变量。
- 在 multiprocessor/multicore 系统中禁用中断是不够的,它不会阻止另一个内核 运行。
- 不用说,不应长时间禁用中断,因为它会阻止某些硬件驱动程序运行。
令x
和y
为主代码和中断代码共享的变量。
我对 volatile
的看法是,它只是而且总是需要用于主代码中也使用的硬件变量和中断变量。
通过禁用中断,保证主代码中 x
和 y
的每次使用都是原子的。
x
和 y
真的需要 volatile
,还是在使用它们强制从 RAM 重新加载变量之前设置内存屏障就足够了?
A)
volatile bool x;
volatile int y[100];
int main(void)
{
while (true) {
disable_interrupts();
if (x)
work(y);
x = false;
enable_interrupts();
}
}
B)
bool x;
int y[100];
int main(void)
{
while (true) {
memory_barrier();
disable_interrupts();
if (x)
work(y);
x = false;
enable_interrupts();
}
}
目标是:
让编译器优化
work()
.能够使用标准库函数,例如
memcpy()
(这些函数不能与volatile
变量一起使用)。
编辑:添加中断示例
interrupts.c
:
extern volatile? int x;
extern volatile? int y;
void interrupt(void)
{
x = true;
REGY1 = y[7];
y[23] = REGY2;
}
内存屏障代替 volatile
就可以了。 Linux 内核开发人员 prefer it that way
有几点需要注意。
- 禁用中断后移动屏障。中断往往发生在最糟糕的时候。
- 在启用中断之前,您需要第二个内存屏障,用于在主程序中写入并在中断处理程序中读取的变量。
- 在 multiprocessor/multicore 系统中禁用中断是不够的,它不会阻止另一个内核 运行。
- 不用说,不应长时间禁用中断,因为它会阻止某些硬件驱动程序运行。