(This is pretty old, and this is an area which changes quite a lot. You should refer to something more recent;Mathieu Desnoyers wrote:
To protect code from being preempted, the macros preempt_disable andNo, it only needs to prevent globally visible side-effects from being moved into/out of preemptable blocks. In practice that means memory updates (including the implicit ones that calls to external functions are assumed to make).
preempt_enable must normally be used. Logically, this macro must make sure gcc
doesn't interleave preemptible code and non-preemptible code.
Which makes me think that if I put barriers around my asm, call, asm trio, noNo global side effects, but code with local side effects could be moved around without changing the meaning of preempt.
other code will be interleaved. Is it right ?
extern int global;
foo = some_function();
foo += 42;
global = foo;
foo += other_thing();
Assume here that some_function and other_function are extern, and so gcc has no insight into their behaviour and therefore conservatively assumes they have global side-effects.
The memory barriers in preempt_disable/enable will prevent gcc from moving any of the function calls into the non-preemptable region. But because "foo" is local and isn't visible to any other code, there's no reason why the "foo += 42" couldn't move into the preempt region.
I am not sure about this last statement. The same reference :
I am just wondering how gcc can assume that I will not modify variables on the
stack from within a function with a memory clobber. If I would like to do some
nasty things in my assembly code, like accessing directly to a local variable by
using an offset from the stack pointer, I would expect gcc not to relocate this
local variable around my asm volatile memory clobbered statement, as it falls
under the category "access memory in an unpredictable fashion".