avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Avr-gcc Produces Incorrect Code with -Os


From: John Regehr
Subject: Re: [avr-gcc-list] Avr-gcc Produces Incorrect Code with -Os
Date: Fri, 16 May 2008 13:08:55 -0600 (MDT)

# define sei()  __asm__ __volatile__ ("sei" ::: "memory")
# define cli()  __asm__ __volatile__ ("cli" ::: "memory")

This has been discussed before (on the avr-libc list, December 2005, just search for '"cli" and "sei" should clobber memory'), and this exact solution was actually proposed by me.

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.

Although making the odd byte-sized flag volatile in order to support synchronization is not a bad idea (and of course we all do it), volatile as a basis for synchronization scales up to large programs with interesting shared data structures extremely poorly. Better we should all use proper locks.

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.

John Regehr




reply via email to

[Prev in Thread] Current Thread [Next in Thread]