[riot-notifications] [RIOT-OS/RIOT] cpu/atmega_common: RTT and RTC support (#8842)

Marian Buschsieweke notifications at github.com
Thu Apr 18 21:25:02 CEST 2019

> An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects.

In other words: Hardware that is somehow mapped into the memory has to be volatile. The state structures you're declaring resides in ordinary memory: It is not changed by the hardware, nor does changing it have any side effects like changing the voltage level at a GPIO pin. This is not a use case for `volatile`.

> Furthermore, at every sequence point the value last stored in the object shall agree with that prescribed by the abstract machine, except as modified by the unknown factors mentioned previously.

``` C
    TIMSK2 &= ~(1 << OCIE2A); /* <-- volatile access */

    [some rtt_state accesses] /* <-- sequence points */

    TIMSK2 |= (1 << OCIE2A); /* <-- volatile access */

This means specifically, that during the access to the `rtt_state`, which are sequence points, "the value last stored in the object [here `TIMSK2`] shall agree with that prescribed by the abstract machine". This means during those accesses, the volatile object `TIMSK2` must have the value "interrupts disabled".


But, as seeing is believing:
``` C
#include <stdint.h>
typedef union {
    uint32_t u32;
    uint8_t u8[4];
} foo_t;

extern foo_t a, b;
int interrupts_enabled;

void bar(void) {
    interrupts_enabled = 0;
    a.u8[0] = 0xa0;
    a.u8[1] = 0xa1;
    b.u8[0] = 0xb0;
    a.u8[2] = 0xa2;
    a.u8[3] = 0xa3;
    interrupts_enabled = 1;
    b.u8[1] = 0xb1;
    b.u8[2] = 0xb2;
    b.u8[3] = 0xb3;

(Partial) output of `gcc -O3 -o foo1.s -S foo.c`:
``` .s
	movl	$-1549622880, a(%rip)
	movl	$1, interrupts_enabled(%rip)
	movl	$-1280134736, b(%rip)

Here the accesses get reordered and combined to a single 32-bit write. (And one access to `interrrupts_enabled` is optimized out, as it was deemed unneeded when not taking side effects into account.)

(Partial) output of `gcc -O3 -o foo2.s -S -DUSE_VOLATILE foo.c`:
``` .s
	movl	$-19534, %eax
	movl	$0, interrupts_enabled(%rip)
	movb	$-80, b(%rip)
	movl	$-1549622880, a(%rip)
	movl	$1, interrupts_enabled(%rip)
	movb	$-79, 1+b(%rip)
	movw	%ax, 2+b(%rip)

Here the accesses to `a` get still optimized and reordered, as they all have been between the two accesses two `interrupts_enabled`. Those accesses to `b` that are supposed to happen while interrupts are disabled are indeed happening then, and those supposed to happen when interrupts are enabled again are happening there.

You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.riot-os.org/pipermail/notifications/attachments/20190418/8c159e2e/attachment-0001.html>

More information about the notifications mailing list