[pso] atomic_read

Octavian Voicu octavian.voicu at gmail.com
Wed Apr 21 10:44:13 EEST 2010


2010/4/21 Alin Popescu <alinpopescu at live.com>:
> Urmatoarea instructiune este atomica?
> atomic_read(&pfifo->fill) == BUFFER_SIZE
>
> Din cate stiu, se translateaza in doua instructiuni asm.
> mov EAX, pfifo->fill.counter
> cmp EAX, BUFFER_SIZE
>
> Exista vreo sansa sa execut comparatia atomic fara spinlock si fara sa
> modific valoarea lui fill?

Din punct de vedere practic poti sa consideri ca operatia e atomica.
Problemele apar cand vrei sa mai executi si alte operatii, de exemplu
sa si modifici variabila pfifo->fill. De obicei folosesti alte
primitive atomice care te lasa sa faci o comparatie si o actualizare
in acelasi timp.

Un caz de utilizare ar fi asta:

if (atomic_cmpxchg(&var, BUFFER_SIZE, 0) == BUFFER_SIZE) {
        /* var era egala cu BUFFER_SIZE; a fost setata la 0 acum */
} else {
        /* var este diferita de BUFFER_SIZE */
}

Totusi, daca vrei sa faci ceva de genul "append one char to buffer but
don't overflow the buffer":

if (atomic_read(&var) == BUFFER_SIZE)
        return;
buffer[atomic_inc_return(&var) - 1] = 'a';

si nu folosesti alt tip de sincronizare, este gresit pentru ca var se
putea modifica intre cele doua operatii atomice.

O varianta corecta ar fi:

i = atomic_inc_return(&var);
if (i <= BUFFER_SIZE)
        buffer[i - 1] = 'a';

Totusi, daca in alta parte te bazezi pe var pentru a-ti spune cate
valori ai in buffer, exista un race in care citesti ultima valoare din
buffer dar n-a fost inca setata de tine.

Pentru implementarea cozilor circulare de la tema trebuie observate
doua chestii:
- pentru write buffer scrii din context proces si citesti din context
intrerupere
- pentru read buffer scrii din context intrerupere si citesti din context proces

Exista doua conditii problematice: buffer empty la read si buffer full
la write. Dar trebuie observat ca daca bufferul NU e empty, el nu se
va goli pana nu vei citi din el. Similar, daca bufferul NU e full, nu
va deveni full pana nu vei scrie in el. Deci e de ajuns testarea
conditiilor buffer full si buffer empty folosind o simpla variabila
atomica, actualizata *dupa* scrierea sau citirea din buffer.

Octavian


More information about the pso mailing list