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: David Brown
Subject: Re: [avr-gcc-list] Avr-gcc Produces Incorrect Code with -Os
Date: Fri, 23 May 2008 10:49:00 +0200
User-agent: Thunderbird 2.0.0.14 (Windows/20080421)

Scott and Roxanne Munns wrote:
Hi everyone,

A lurker pops his head out of his hole for a comment - please don't shoot
me!  :)

Normally, critical sections are supposed to be used to protect *data*, not
*code*.  The atomic operations listed in the URL are doing very specific
atomic operations on data.  In other words, they also follow the theme of
protecting data, not code.  It seems to me that applying the "critical"
attribute to generic functions can lead a programmer to start thinking in
terms of protecting code instead of data.  Eventually that can lead to a
disastrous result, especially if you ever work with multi-threaded code.

All of the examples I have seen in the thread so far were used for very
simple data-modifying operations that are suitable for inlining.  I think
that is acceptable use of "critical".  However, not everyone will follow
that principle - they may treat "critical" as a cure-all.

In the past, I have solved the critical section problem by using some
#defines.  Unfortunately, I had to use THAT_OTHER_COMPILER(tm).  I'd give
you the exact definitions, but I'm at home and don't have access to my work
code.

DECLARE_CRITICAL_SECTION - at the top of each function with a critical
section - creates a variable to store SREG
BEGIN_CRITICAL_SECTION - records the value of SREG and clears global
interrupt flag
END_CRITICAL_SECTION - restores SREG

Technically it's no better than doing the code inline, but it is more
self-documenting.

Hope this generates some more ideas/discussion,
Scott


I won't shoot, but I don't entirely agree with you. As far as your DECLARE_CRITICAL_SECTION macros are concerned, these appear to be nothing more than macros for the standard SREG/cli pattern for protecting code. If you feel that makes your code clearer, then it's the right way for you to protect your critical code. Implementing it in avrgcc would take nothing more than the macro definitions in a header file.


As for protecting code or data, I think you are mixing some concepts. At the lowest level, there are directly accessible units of memory. At a higher level, there is data, which consists of one or more memory units, and specified operations on those memory units. So protecting data means protecting code that accesses that data's memory units.

The atomic builtins that gcc has for the Itanium protect certain types of code that access certain types of data - single operations on single memory units. This provides a building block to provide useful higher level OS primitives such as locks or monitors (i.e., critical sections), that protect code blocks - and thus protect the data accessed within the protected code blocks.

In general, you require several operations to manipulate data and keep it in a consistent state. For example, when adding data to a queue you must add the data and increment a tail pointer (or size variable, if you prefer) within a protected block. There is no way to protect the data itself in C (with C++, you can protect the code for each operation on a class). At best, you could protect some single memory units of data, if the underlying target supported it (which the AVR does not).

I don't quite see how you conclude that protecting code would lead to disastrous results, especially in multi-threaded code. Certainly excessive locking will hinder performance - that is true for any locking or protection mechanism, and particularly true of disabling interrupts.

Perhaps you are thinking of OS locks such as semaphores or mutexes, which might be *named* for a data structure. For example, you might have a queue, and a lock called "queueLock". Before manipulating the queue, you acquire "queueLock", do the manipulation, then release the lock. But you are still protecting the code sequence, not the data itself - the data is indirectly protected by always using protected code sequences to access it.

mvh.,

David




reply via email to

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