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: Weddington, Eric
Subject: RE: [avr-gcc-list] Avr-gcc Produces Incorrect Code with -Os
Date: Fri, 16 May 2008 09:32:48 -0600

 

> -----Original Message-----
> From: 
> address@hidden 
> [mailto:address@hidden
> org] On Behalf Of Mark Litwack
> Sent: Friday, May 16, 2008 9:05 AM
> To: address@hidden
> Subject: Re: [avr-gcc-list] Avr-gcc Produces Incorrect Code with -Os
> 
> On Friday 16 May 2008 08:05:41 am Paulo Marques wrote:
> > ....
> >
> > Note! This is not even the worst case for this 
> optimization. The worst
> > case I've seen is something like:
> >
> > int my_flag;
> >
> > ....
> > cli();
> > my_flag = 0x1234;
> > sei();
> > ....
> >
> > Contrary to what you might expect, that my_flag access isn't being
> > protected by the cli/sei pair, and might be reordered by 
> the compiler
> > (and "might" here means "it has happened", not some 
> theoretical scenario).
> >
> > Currently, the official way of doing something like that is 
> using the
> > macros provided in <util/atomic.h>.
> 
> Wow.  I think the cli()/sei() construct is used fairly
> universally, and it's also in the avr-libc docs.
> 

Acutally it's not. What is more appropriate is this:

uint8_t old_sreg = SREG;
cli();
// code
SREG = old_sreg;

You don't want to blindly set the interrupts after they have been
cleared. You want to *restore the interrupts to its previous state*.
This is why the status register (SREG) is saved and restored as it
contains the 'I' flag, which is the global interrupts flag. Restoring
SREG restores the previous state of the globabl interrupts flag.

Really the only time that one should see cli()...sei() is in the
initialization of the chip, and generally there is a lot more code than
one line between the two.

Eric




reply via email to

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