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);
produces an infinity 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
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Reply via email to