John Regehr wrote:
# define sei() __asm__ __volatile__ ("sei" ::: "memory")
# define cli() __asm__ __volatile__ ("cli" ::: "memory")
<snip>
Adding these clobbers is an extremely good idea because they make
cli/sei act like proper locks, in two senses. First, they prevent
reordering of computations as has been discussed here. Second, they
force data cached in registers to be written to RAM when the interrupt
lock is released. Both of these are important.
Here's a subtle but important point: If you consistently protect shared
data with clobbering locks, you don't need to make data volatile when it
is shared between interrupts and main(). Of course you still need
volatile for accessing hardware registers.
Well, isn't the net effect of volatile simply a more fine-grained
clobbering lock?
<snip>
The downside is that a memory clobber like that drops all
optimizations of global variables that the compiler might be
temporarily storing in registers. So, it actually hurts performance
for code unrelated to the critical section.
We studied the impact of adding clobbers to critical sections in TinyOS
and found that both code size and CPU usage actually decreased slightly
due to the clobbers. No idea why. Details here:
http://www.cs.utah.edu/~regehr/papers/plos06b.pdf
TinyOS currently clobbers memory on every cli/sei.
That's a counter-intuitive result. The "No idea why." part makes me a
little squinty-eyed. It certainly *could* be a generalizable result,
but then again it might be an artifact of your code structure.
I could see including both clobbering and non-clobbering flavors of
sei()/cli() in avrlibc -- then we can have a whole new and entertaining
argument about whether the old names sei()/cli() should have the new or
old behavior :) :)
-dave
John Regehr
_______________________________________________
AVR-GCC-list mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list