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: Dave Hansen
Subject: Re: [avr-gcc-list] generic queue library for AVR GCC?
Date: Thu, 18 Nov 2004 09:51:55 -0500

From: "David Brown" <address@hidden>
[...]
I think it might be worth adding a couple of comments here, especially as I
have written queing code for the msp using "critical" functions.

#define bufferSize 32                    // Power-of-two makes % easy
static uint8 buffer[bufferSize];
static uint8 start, length;                // Note - no need for "volatile"
or anything

I disagree with your last comment.

Critical sections and "volatile" are orthoganal concepts. The first prevents a series of program statements from being interrupted. The latter prevents the compiler from making certain optimizations when accessing variables. Both are useful when dealing with multiple threads of execution (such as intterupt service routines).

The code you wrote might work without "volatile," but without a more careful analysis, I don't think it's entirely safe to say there's no need for it. An aggressive optimizer, working within its rights as defined by the standard, could ruin your whole day.


void critical addToBuffer(uint8 b) {
if (length >= bufferSize) return; // Safe to write this sort of thing
    buffer[(start + length) % bufferSize] = b;
    length++;
}

uint critical getFromBuffer(void) {
    uint b;
    if (!length) return 0;
    length--;
    b = buffer[start];
    start = (start + 1) % bufferSize;
    return b;
}

[...]

The "critical" attribute doesn't hide anything more or less than a decent
set of macros or inline functions.  It makes it harder to get it wrong,
which is a good thing.  I suppose there is a danger of newbies mistakanly
using "critical" when they really mean "I want this function to run as fast
as possible".

Personally, I would prefer the adjective "atomic" to "critical," but I suppose GreenPeace would object...

Such an attribute is useful if the critical section can be sensibly encapsulated in a function. I'm not completely convinced that is always the case. But in the project I'm currently working on, all the critical sections are encapsulated within functions.

It does invite abuse, however: it is harder to account the cost for code you don't write. To steal some of your code for an example:

  void addToBuffer(uint8 b) {
       CS_STATE_BUFFER csb;

       csb = begin_critical_section();

       if (length < bufferSize){
          buffer[(start + length) % bufferSize] = b;
          length++;
       }

       end_critical_section(csb);
  }

Given appropriate definitions of CS_STATE_BUFFER, begin_critical_section(), and end_critical_section(), this would generate code nearly identical to your original function. But it's easier to see the costs, and the implications of modifying the code. IMHO, anyway.

Regards,
  -=Dave




reply via email to

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