M0 : bad C11 atomics
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
GNU Arm Embedded Toolchain |
Confirmed
|
Undecided
|
Unassigned |
Bug Description
Hi,
this is mostly a rehash of https:/
Here's the essential:
Compiling the following code with "arm-none-eabi-gcc -save-temps -mcpu=cortex-m0 -mthumb -fverbose-asm at.c"
**** at.c ****
#include <stdatomic.h>
atomic_flag aflag = ATOMIC_FLAG_INIT;
int main(void) {
while (1) {
while (atomic_
atomic_
}
return 0;
}
*********
gives the following intermediate assembly :
********* at.s (excerpt) ****
main:
push {r7, lr} @
add r7, sp, #0 @,,
.L3:
@ t1.c:16: while (atomic_
nop
.L2:
@ t1.c:16: while (atomic_
ldr r3, .L4 @ tmp114,
ldrb r2, [r3] @ tmp115,
movs r1, #1 @ tmp116,
strb r1, [r3] @ tmp117,
uxtb r3, r2 @ _1, tmp115
@ t1.c:16: while (atomic_
cmp r3, #0 @ _1,
bne .L2 @,
........
**********
The problem is the "ldrb ...strb" sequence which is not atomic. M0 cores do not have strex/ldrex , they require an interrupt disable around the protected operation (mrs + cpsid + msr).
I believe gcc shouldn't silently generate a non-atomic sequence like this !
description: | updated |
Changed in gcc-arm-embedded: | |
status: | New → Confirmed |
I can still reproduce with GCC 9.2.1 (9-2019-q4-major):
main: flag_test_ and_set( &aflag)); flag_test_ and_set( &aflag)); flag_test_ and_set( &aflag)); flag_test_ and_set( &aflag));
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 1, uses_anonymous_args = 0
push {r7, lr} @
add r7, sp, #0 @,,
.L3:
@ at.c:7: while (atomic_
nop
.L2:
@ at.c:7: while (atomic_
ldr r3, .L4 @ tmp112,
ldrb r2, [r3] @ tmp113,
movs r1, #1 @ tmp114,
strb r1, [r3] @ tmp115,
uxtb r3, r2 @ _1, tmp113
@ at.c:7: while (atomic_
cmp r3, #0 @ _1,
bne .L2 @,
@ at.c:8: atomic_flag_clear( &aflag);
ldr r3, .L4 @ tmp116,
dmb ish
movs r2, #0 @ tmp117,
strb r2, [r3] @ tmp118,
dmb ish
@ at.c:7: while (atomic_
b .L3 @
.L5:
.align 2
.L4:
.word aflag
.size main, .-main
.ident "GCC: (GNU Tools for Arm Embedded Processors 9-2019-q4-major) 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599]"