[En-Nut-Discussion] Fwd: Not fixed!!!: Re: confirmed!!! Re: NutOS 4.4.0 on ARM7: possibly bug in NutEnterCritical / NutExitCritical

duane ellis ethernut at duaneellis.com
Sun Feb 24 21:17:34 CET 2008


Nathan Moore wrote:

>> I don't think that this really makes sense even if 
>> it were the reason that "memory" is in the clobber 
>> list since an IRQ could pop in and change stuff in 
>> memory at any time when interrupts aren't disabled,
>> not just right after interrupts have been reenabled.

True, IRQs can happen at any time. But that is why you
lock the system before you access things like the head
of a linked list, and only access it after IRQs are disabled.
GCC needs to know that.

The problem here is that GCC needs to know that this 
operation (irq enable/disable) effectively acts like 
a *function* call, even though it was in-line.

One could also create a special 'inline-assembly' 
function that makes use of a special CPU opcode. For 
example, newer ARM chips have a "clz" - count 
leading zeros instruction. There is no means to
describe that in the context of C.

There are others, for example C has SHIFT, but not
any concept of "rotate" 

That (and other) special instructions do not
act like a "memory" barrier, they only act upon
registers, but GCC does not know this.

Thus do not need the 'memory' tag.

if all inline assembly acted as a memory barrier, 
then opportunities to optimize are reduced.

Remember, you can allow GCC to choose which
register is used by the inline assembly.
Hence, it can optimize the choice as appropriate.

>> Casting variables to volatile and use the variables 
>> that might change within the critical section rather
>> than after it would be the right thing to do.

One does not cast a variable like this to 'volatile'
the variable must be declared as such, otherwise
you will not get what you want.

 >> The counter argument to this is that correctness trumps backwards 
API compatibility.

Agree 100%, without question.

 >> I'm not really sure why these things still work at all, but if you 
made it a
 >> thread local varialbe it would work better: CurrentThread->CriticalDepth

The truth lies elsewhere, what you are describing is a scheduler block.

It is common for an OS to have two levels of criticality.

(1) is like Linked List management - you just must have associated IRQs 
disabled.
That is a well known thing, the subject of this long series of emails.

(2) is the subject of 'scheduler' context switching blocking, or "second 
level handlers".

    here are two good references:
            http://en.wikipedia.org/wiki/Interrupt_handler

    The commercial package, SMX calls them 'link-service-routines' or "lsr"
    And has some diagrams that help explain.

            http://www.smxrtos.com/articles/lsr_art/lsr_art.htm
            http://www.smxrtos.com/articles/techppr/defint.pdf

    In the SMX case, they do it via the "INVOKE" macro.

-Duane.







More information about the En-Nut-Discussion mailing list