Considering a 32-bit system (such as an ARM RISC MCU), how can one ensure that 16-bit variables are written/ read in an atomic way? Based on this doc, If I understood correctly, both 16-bit and 8-bit operations are atomic, but only assuming the memory is aligned. Question is, does the compiler always align the memory to 32-bit words (excluding cases like packed structures)?
The rationale here is to use uint16_t
whenever possible instead of uint32_t
for better code portability between 32-bit and 16-bit platforms. This is not about typedefing a type that is different on either platform (16 or 32 bit).
CodePudding user response:
The compiler may align any (scalar) object as it pleases unless it is part of an array or similar, there's no restriction or guarantee from C. Arrays are guaranteed to be allocated contiguously however, with no padding. And the first member of a struct/union is guaranteed by be aligned (since the address of the struct/union may be converted to a pointer to the type of the first member).
To get atomic operations, you have to use something like atomic_uint_fast16_t
(stdatomic.h) if supported by the compiler. Otherwise any operation in C cannot be regarded as atomic no matter the type, period.
It is a common mistake to think "8 bit copy is atomic on my CPU so if I use 8 bit types my code is re-entrant". It isn't, because uint8_t x = y;
is not guaranteed to be done in a single instruction, nor is it guaranteed to result in atomic machine code instructions.
And even if an atomic instruction is picked, you could still get real-time bugs from code like that. Example with pseudo-machine code:
- Store the contents of
y
in register A. - An interrupt which only occurs once every full moon fires, changing
y
. - The old value of
y
is stored inx
- yay, this is an atomic instruction! - Now
x
has the old, outdated value.
Correct real-time behavior would have been to either completely update x
before the interrupt hit, or alternatively update it after the interrupt hit.
CodePudding user response:
The place were I work has a special agreement with all the relevant compiler suppliers that they are responsible for notifying our tool chain experts of cases were that assumption is not applicable.
This turned out to be necessary, because it otherwise cannot be reliably determined. Documentation does not say and the standard even lesss.
Or that is what the tooling people told me.
So it seems that for you the answer is: Ask the supplier.