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

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

Re: [avr-gcc-list] generic queue library for AVR GCC?


From: David Brown
Subject: Re: [avr-gcc-list] generic queue library for AVR GCC?
Date: Wed, 17 Nov 2004 10:43:03 +0100

>Howabout:
>
>typedef unsigned char critical_section;
>
>static inline void begin_critical_section(critical_section * s) {
>*s = SREG;
>cli();
>}
>
>static inline void end_critical_section(critical_section * s) {
>SREG = *s;
>}
>
>Then you can put all your variable definitions away at the top of the
>function they are used in, and call begin and end symmetrically.

How is any better?  With your new code, you must write:

void foo(void) {
    critical_section cs;
    begin_critical_section(&cs);
    ...
    end_critical_section(&cs);
}

instead of

void foo(void) {
    critical_section cs;
    cs = begin_critical_section(cs);
    ...
    end_critical_section(cs);
}

All you have done is added a layer of indirection, which might well cause
the compiler to force the sreg storage onto the stack instead of keeping it
as a register.

>
>> you still have the problem of what if you put a return in statements.
>> You'd leave the critical section without restoring interrupts.
>
>That was the advantage of my previous solution that used #define to >open
>and close braces around the section - but that constrains you more.
>

Actually, you'd get the same problem if you put a return statement in the
middle of the critical section.  I don't believe there is any safe way to
guarentee that the critical section is exited properly if it is first
entered, without going beyond normal C.  Use a c++ object with a constructor
that reads SREG and disables interrupts, and a destructor which restores the
SREG would work.  In mspgcc, there is a new function attribute "critical"
implemented which effectively wraps a function in the save/disable/restore
code.


>--
>Richard Urwin






reply via email to

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