问题
Let x
and y
be variables that are shared between main code and interrupt code.
My idea of volatile
is that it is only and always needed for hardware variables and interrupt variables that are also used in main code.
Every usage of x
and y
in the main code is guaranteed to be atomic by disabling interrupts.
Do x
and y
really need to be volatile
, or is it enough to put a memory barrier before using them to force reloading the variables from 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();
}
}
The objectives are:
To let the compiler optimize
work()
.Be able to use standard library functions such as
memcpy()
(those aren't made to be used withvolatile
variables).
Edit: add interrupt example
interrupts.c
:
extern volatile? int x;
extern volatile? int y;
void interrupt(void)
{
x = true;
REGY1 = y[7];
y[23] = REGY2;
}
回答1:
Memory barriers instead of volatile
are fine. Linux kernel developers prefer it that way
There are a few things to watch out for.
- Move the barrier after disabling interrupts. Interrupts tend to happen at the worst times.
- You need a second memory barrier before enabling interrupts, for variables that are written in the main program, and read in the interupt handler.
- Disabling interrupts is not enough in a multiprocessor/multicore system, it doesn't prevent another core from running.
- Needless to say, interrupts should not be disabled for extended periods of time, as it can prevent some hardware drivers from functioning.
来源:https://stackoverflow.com/questions/56791401/volatile-vs-memory-barrier-for-interrupts