Zagwozdka w C Keil.

I ja dokładnie to napisałem:

"`volatile` nie oznacza, że kompilator gwarantuje atomiczny dostęp do zmiennej".

Reply to
Queequeg
Loading thread data ...

Autopoprawka: danych. Magistrala danych.

Reply to
Queequeg

Obsługuje, tylko nie domyślnie :)

Ja kompiluję z:

--disable-mime-strict-charset

--with-mime-default-charset=ISO-8859-2

I potem w ~/.tin/attributes:

scope=pl.*,alt.pl.* mm_network_charset=ISO-8859-2 undeclared_charset=ISO-8859-2

Reply to
Queequeg

Po atrybucie volatile :-)

J.

Reply to
J.F.

Dnia Thu, 14 Feb 2019 13:36:34 +0100, Grzegorz Niemirowski napisał(a):

Ale wychodzi na to, ze niezbedna.

Liczenie cykli procesora w programie w C ?

Jak dobrze przepisze, to i kompilator nie bedzie musial ich wylaczac.

J.

Reply to
J.F.

Czemu w przerwaniu a nie w sygnale?

Czemu w przerwaniu a nie w innym wątku?

Czemu w przerwaniu a nie przez sprzęt?

Reply to
Queequeg

Jakby na jedno wychodzi.

Na jednym procesorze to nadal to samo, ale teraz modne wielo rdzeniowe ... i sie komplikuje

W sensie, ze nie ma co przerwan wylaczac, skoro sprzet to robi? No moze i racja ... bo problem nadal jest ...

J.

Reply to
J.F.

J.F. <jfox snipped-for-privacy@poczta.onet.pl> napisał(a):

Nijak na to nie wychodzi, ponieważ ludzie od lat radzą sobie bez tego. Poza tym:

powyższe :)

Nie chodzi o długość opóźnienia ale o stałość. Poza tym czasem się liczy.

Reply to
Grzegorz Niemirowski

W dniu 2019-02-14 o 10:57, Queequeg pisze:

Oki, przegapiłem to 'nie '.

Reply to
Janusz

Chociaż by z powodu występowania możliwości błędnego odczytu wartości 0 dla tej zmiennej gdy jest czytana połówkami. Mój przypadek.

Zastanawiam się, czy gdyby kompilator zrobił odczyt wielokrotny, czy było by to "moralnie" poprawne, czy nadal miało by znamiona łaty?

Dlaczego miał by tak zrobić? Ponieważ volatile (w moim przekonaniu) mówi kompilatorowi, że może się spodziewać problemów z tą zmienną i nie może zakładać, że uda się ją odczytać etapowo (tak samo jak np. nie ma sensu ją buforować, tylko za każdym razem trzeba czytać).

Miłego. Irek.N.

Reply to
Irek.N.

Faktycznie tak robi, na całe dzielenie wył przerwania ale można ten problem obejść :)

void test2( unsigned int val ) {div_t wynik; wynik=div(65535U,val); e10: bc 01 movw r22, r24 e12: 8f ef ldi r24, 0xFF ; 255 e14: 9f ef ldi r25, 0xFF ; 255 e16: 0e 94 f7 08 call 0x11ee ; 0x11ee <__divmodhi4>

return 1; }

static __inline__ uint8_t __iCliRetVal(void) { cli(); e1a: f8 94 cli //val = / val; ATOMIC_BLOCK(ATOMIC_FORCEON) { ivar = wynik.quot; e1c: 70 93 14 02 sts 0x0214, r23 ; 0x800214 <ivar+0x1>

e20: 60 93 13 02 sts 0x0213, r22 ; 0x800213 <ivar>

return 1; }

static __inline__ void __iSeiParam(const uint8_t *__s) { sei(); e24: 78 94 sei

Da się? da sie :) ale prawda jest taka że trzeba mu cały czas patrzyć na ręce czy nam czegoś nadmiernie nie zoptymalizował.

Reply to
Janusz

Irek.N. snipped-for-privacy@jakis.taki.jest.pl> napisał(a):

Na szczęście co mówi volatile to jest zdefiniowane w standardzie a nie w czyichś przekonaniach :)

volatile dotyczy wyłącznie optymalizacji. "Problemy" ze zmienną mogą brać się z wielu różnych przyczyn, nie tylko z przerwań. Jest też np. DMA. Nie ma sensu rozważać volatile w kontekstach, do których nie zostało stworzone lub też oczekiwać, że kompilator przejmie rolę menedżera pamięci lub inną, należącą do systemu operacyjnego lub programisty.

Reply to
Grzegorz Niemirowski

Ale co miałoby to rozwiązać? Wartość może zmieniać się za każdym odczytem, i co wtedy? Ma się zapętlać ad vitam aeternam?

Ty natomiast zakładasz z góry, że wartość tej zmiennej zmienia się wolniej niż pętla jest w stanie ją sprawdzić. Nadgorliwość gorsza od... :)

Mateusz

Reply to
Mateusz Viste

Taka typowa sekcja krytyczna to jeszcze wymaga systemu operacyjnego, a przynajmniej czegos na ksztalt, z przelaczaniem procesow ..

Ha, moze i faktycznie C++ trzeba uzyc nawet na 8051 - dostep do zmiennych obiektu da sie przez wydzielone funkcje, ktore zadbaja o potrzebne rzeczy :-)

J.

Reply to
J.F.

Wiem że masz rację, wiesz, myślenie życzeniowe :)

Miłego. Irek.N.

Reply to
Irek.N.

I całe szczęście Panie, i całe szczęście. Czy w C ktoś pisze sterowanie do silników samolotów? ;)

Miłego. Irek.N.

Reply to
Irek.N.

Pisze :)

formatting link
formatting link

Reply to
Queequeg

No tak, ale volatile przed tym nie chroni.

To przekonanie to to, co podpowiadałaby intuicja, ale z punktu widzenia standardu jest błędne.

Zobacz chociażby tutaj:

formatting link
Strona 25, punkty 2 i 3, później też strona 121, punkt 6.

Tu nie ma mowy o atomicznym odczycie zmiennej tylko o nieoptymalizowaniu dostępu do tej zmiennej.

Oczywiście na logikę chcielibyśmy, żeby zmienna nie zmieniła wartości w trakcie jej odczytu, ale do tego po prostu służą inne mechanizmy niż modyfikator volatile.

Reply to
Queequeg

Czemu? Na 8-bitowcach zwykle nie mamy OS ani wielu procesów, mamy jedynie przerwania, więc w sekcji krytycznej chcemy po prostu, żeby funkcje obsługi przerwań poczekały na koniec sekcji krytycznej. Czyli:

  1. Wyłączamy przerwania
  2. Odczytujemy jedną połówkę zmiennej
  3. Timer zgłasza przerwanie (ustawia flagę)
  4. Odczytujemy drugą połówkę zmiennej
  5. Włączamy (przywracamy) przerwania
  6. Przerwanie zgłoszone przez timer jest obsługiwane

To, czy programujemy obiektowo, czy nie, to zupełnie inny poziom abstrakcji niż to, o czym tutaj mówimy :)

Reply to
Queequeg

Sprawdziłem, nie ma różnicy w wygenerowanym kodzie.

Diff:

#v+

--- test-no-static.s 2019-02-16 23:19:27.993290080 +0100

+++ test-static.s 2019-02-16 23:19:20.653290321 +0100 @@ -29,7 +29,7 @@ .L6: .align 2 .L5:

- .word i

  • .word .LANCHOR0 .size fn1, .-fn1 .align 2 .global fn2 @@ -45,8 +45,14 @@ .L9: .align 2 .L8:

- .word i

  • .word .LANCHOR0 .size fn2, .-fn2

- .comm i,4,4

  • .bss
  • .align 2
+.LANCHOR0 = . + 0
  • .type i, %object
  • .size i, 4
+i:
  • .space 4 .ident "GCC: (Raspbian 4.9.2-10) 4.9.2" .section .note.GNU-stack,"",%progbits #v-

Tak, to zmienia postać rzeczy.

Z samym `int i;` fn1 wygląda wtedy:

#v+ ldr r3, .L5 ldr r3, [r3] .L2: cmp r3, #42 bne .L2 #v-

A ze statycznym:

#v+ .L2: b .L2 #v-

Tak... to zrobił ciekawie.

Jeśli main jest niestatyczne, to wygenerował ciało fn1() a jeśli jest statyczne, to zamienił na nieskończoną pętlę.

Nie wiem czemu to:

#v+ static int i; void fn1(void) { while (i != 42) ; } static void fn2(void) { i = 40; } void fn3(void) { fn1(); fn2(); } #v-

spowodowało wygenerowanie ciała fn1:

#v+ ldr r3, .L5 ldr r3, [r3] .L2: cmp r3, #42 bne .L2 #v-

Reply to
Queequeg

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.