Forum: Compiler & IDEs Cortex-M4: atomares Load oder Store


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Raoul D. (raoul_d219)


Lesenswert?

Es geht um Cortex-M4+Fpu.
Der g++ macht aus
1
   volatile uint64_t x1;
2
   volatile uint64_t x3;
3
4
int main(){
5
    while(true) {
6
        x3 = x1;
7
    }
8
}

ein
1
main:
2
ldr     r0, .L4 @ tmp118,
3
ldr     r1, .L4+4       @ tmp119,
4
.L2:
5
ldrd    r2, [r0]        @ x1.0_1, x1
6
strd    r2, [r1]        @ x1.0_1, x3
7
b       .L2             @

oder manchmal auch ein
1
vldr.64 d7, [r5]        @ int   @ x1.0_1, x1
2
vstr.64 d7, [r4]        @ int   @ x1.0_1, x3

wenn der Registerdruck zunimmt. Also ein atomares load oder store. Ich 
meine keine atomaren RMW-Zyklen, das kann der Cortex-M generell nicht 
(dazu existiert ldrex/strex oder IRQ-Sperre).

Die Frage nun: gibt es ein GCC-intrinsic, womit ich feststellen kann, 
bis zu welcher Größer ein fundamentaler DT atomar gelesen oder 
geschrieben werden kann. Auf einer 32-Bit CPU kann ich sicher 32-Bit 
annehmen, aber hier geht ja auch 64-Bit.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

sig_atomic_t ?

von Raoul D. (raoul_d219)


Lesenswert?

Johann L. schrieb:
> sig_atomic_t ?

Das ist ein Typ-Alias für int. Und der ist 32_bit, so wie es auch
1
# define SIG_ATOMIC_WIDTH 32

sagt.

Das wäre ja auch meine Vermutung gewesen. Ich bin nun etwas erstaunt, 
dass das auch für 64-Bit geht.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Raoul D. schrieb:
> Ich bin nun etwas erstaunt, dass das auch für 64-Bit geht.

Was heißt es "geht auch" für 64-Bit?

Das Makro sagt, dass es für (unsigned) int geht.  Mehr nicht.

Ansonsten z.B. atomic Built-ins

https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html

: Bearbeitet durch User
von Vincent H. (vinci)


Lesenswert?

Raoul D. schrieb:
> Das wäre ja auch meine Vermutung gewesen. Ich bin nun etwas erstaunt,
> dass das auch für 64-Bit geht.

Tut es nicht. Weder LDRD noch VLDR ist atomar.

https://developer.arm.com/documentation/ddi0403/latest/
(siehe S. A3-80)

std::atomic<T>::is_always_lock_free dürfte ein guter Indikator für deine 
zweite Frage sein:
1
#include <atomic>
2
3
static_assert(std::atomic<uint32_t>::is_always_lock_free);
4
static_assert(std::atomic<uint64_t>::is_always_lock_free); // Fails on 32bit M4

von J. S. (jojos)


Lesenswert?

Sind in CMSIS keine Makros dafür vorhanden?

von Raoul D. (raoul_d219)


Lesenswert?

Vincent H. schrieb:
> Raoul D. schrieb:
>> Das wäre ja auch meine Vermutung gewesen. Ich bin nun etwas erstaunt,
>> dass das auch für 64-Bit geht.
>
> Tut es nicht. Weder LDRD noch VLDR ist atomar.
>
> https://developer.arm.com/documentation/ddi0403/latest/
> (siehe S. A3-80)

Perfekt, danach habe ich gesucht!

von Arm (arm_arm)


Lesenswert?

LDRD wird als 2 Instruktionen ausgeführt, diese kann aber nicht durch 
eine exception unterbrochen werden (s. B1 - 543, im Kontrast zu LDM).

Damit sollte LDRD auf single cores effektiv doch atomar sein?

von Bauform B. (bauformb)


Lesenswert?

Arm schrieb:
> LDRD wird als 2 Instruktionen ausgeführt, diese kann aber nicht durch
> eine exception unterbrochen werden (s. B1 - 543, im Kontrast zu LDM).

An der Stelle wird LDRD/STRD nicht erwähnt und in A3.5.3 (S.80) heißt es
1
LDM, LDC, LDC2, LDRD, STM, STC, STC2, STRD, PUSH, POP, VLDR, VSTR,
2
VLDM, VSTM, VPUSH, and VPOP instructions are executed as a sequence
3
of word-aligned word accesses.
4
(...)
5
If an instruction is executed as a sequence of accesses according to
6
these rules, some exceptions can be taken in the sequence and cause
7
execution of the instruction to be abandoned. On exception return,
8
the instruction that generated the sequence of accesses is re-executed
9
and so any accesses that had already been performed before the exception
10
was taken might be repeated.
> Damit sollte LDRD auf single cores effektiv doch atomar sein?

Ich würde mich nicht darauf verlassen.
Außerdem darf man "core" nicht zu eng sehen. Zum Beispiel ist DMA auch 
ein Bus Master, genau wie die CPU und beide sind (nur) per 32 Bit 
angebunden. Theoretisch(?) könnte ein Buffer per DMA gefüllt werden und 
zur Verarbeitung liest jemand mit LDRD.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.