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

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

Re: [avr-gcc-list] BUG? Comparing of words error.


From: David Brown
Subject: Re: [avr-gcc-list] BUG? Comparing of words error.
Date: Fri, 20 Jan 2006 09:01:16 +0100

Hi,

Thanks for correcting my typo.

For many uses, the traditional disabling of interrupts is actually a better
solution, in that it is deterministic.  The double-read solution is
particularly good for slowly changing variables, and if you don't want to
disable interrupts (for example, if the function could be called with
interrupts enabled or disabled, this saves you doing save/restore code on
the interrupt state).  It also works well on bigger processors, when
user-level code might not have access to interrupt states.

mvh.,

David



> Sorry, a mistake:
>    Original produces a *fiction* loop, without
>    an '*addr' reading.
>
> On Thursday 19 January 2006 17:46, David Brown wrote:
> > There have already been a dozen answers pointing out the O/P's problem.
I
> > thought you might like to know, however, that there is another way to do
an
> > atomic read of such a counter without disabling interrupts, which can be
> > useful in some circumstances.  If you have complicated and slow
interrupt
> > routines, or high frequency interrupts, then it's probably not a great
idea
> > as it is non-deterministic.
> >
> > unsigned short atomic_read_short(unsigned short *addr) {
> >     unsigned short a, b;
> >     a = (volatile)(*addr);
> >     do {
> >         b = (volatile)(*addr);
> >         if (a == b) return a;
> >         a = b;
> >     };
> > }
>
> Yes, this is a very beautiful idea.
>
> Only one note: to force reading from '*addr'
> it is necessary a small correction.
> Original:
>     do {
>         b = (volatile)(*addr);
>         if (a == b) return a;
>         a = b;
>     } while (1);
> produce a fiction loop:
>    .L2:
>         cp r24,r18
>         cpc r25,r19
>         breq .L7
>         movw r24,r18
>         rjmp .L2
>
> and after correction:
>     do {
>         b = *(volatile unsigned short *)addr;
>         if (a == b) return a;
>         a = b;
>     } while (1);
> works true:
>    .L2:
>         ld r18,Z
>         ldd r19,Z+1
>         cp r24,r18
>         cpc r25,r19
>         breq .L7
>         movw r24,r18
>         rjmp .L2
>
> Regards,
> Dmitry.
>
>
>
> _______________________________________________
> AVR-GCC-list mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
>





reply via email to

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