[Top][All Lists]

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

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

From: Geoffrey Wossum
Subject: Re: [avr-gcc-list] generic queue library for AVR GCC?
Date: Tue, 16 Nov 2004 13:36:14 -0600
User-agent: KMail/1.7.1

On Tuesday 16 November 2004 11:53 am, Richard Urwin wrote:

> But you still have to declare a variable to hold the return value, and
> that was what broke the #define version.

That's actually the main thing I like about the NutOS critical sections that 
push and pop directly from the stack.  No need to declare a variable to go 
along with it.

> typedef enum {cs_start, cs_end} cs_enum;
> static inline unsigned char critical_section(cs_enum dir)
> {
>         static unsigned char s;
>  switch(dir)
>  {
>  case cs_start:
>   s = SREG;
>          cli();
>   break;
>  case cs_end:
>   SREG = s;
>  }
> }

This doesn't look like it would handle nested critical sections.  I actually 
do that quite a lot.  For instance, in my FIFO routines I use a critical 
section to protect access to the FIFO counters and pointers.  Sometimes I 
want multiple elements to be enqueued/dequeued from the FIFO as an atomic 
unit.  For this, I'll wrap a critical section around all the 
enqueues/dequeues.  That type of use would break this, I believe.  You could 
probably fix it in the majority of usages by adding a counter, though.  You 
only store SREG in s when the counter is 0, and you only restore SREG when 
counter is being decremented back to 0.

If you didn't want to declare a variable to hold SREG, and you didn't want to 
manipulate the stack directly, you could probably do something like this:

#define CRITICAL_SECTION(_stmts) \
    do { \
        uint8_t sreg_save = SREG;  \
        cli();  \
        { _stmts }  \
        SREG = sreg_save;  \
    } while (0);

To use it would look something like:

    CRITICAL_SECTION((    // notice the double paranthesis
        fifo_push(&fifo, c1);
        fifo_push(&fifo, c2);

I think that would work.  I'm not really sure I'd like to use it, though.  
Plus, you still have the problem of what if you put a return in statements.  
You'd leave the critical section without restoring interrupts.  Your stack 
would be fine, however, unlike if you did that with the NutOS version. 

Geoffrey Wossum
Long Range Systems - http://www.pager.net

reply via email to

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