xref: /OK3568_Linux_fs/kernel/Documentation/translations/it_IT/process/volatile-considered-harmful.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun.. include:: ../disclaimer-ita.rst
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun:Original: :ref:`Documentation/process/volatile-considered-harmful.rst <volatile_considered_harmful>`
4*4882a593Smuzhiyun:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun.. _it_volatile_considered_harmful:
7*4882a593Smuzhiyun
8*4882a593SmuzhiyunPerché la parola chiave "volatile" non dovrebbe essere usata
9*4882a593Smuzhiyun------------------------------------------------------------
10*4882a593Smuzhiyun
11*4882a593SmuzhiyunSpesso i programmatori C considerano volatili quelle variabili che potrebbero
12*4882a593Smuzhiyunessere cambiate al di fuori dal thread di esecuzione corrente; come risultato,
13*4882a593Smuzhiyuna volte saranno tentati dall'utilizzare *volatile* nel kernel per le
14*4882a593Smuzhiyunstrutture dati condivise.  In altre parole, gli è stato insegnato ad usare
15*4882a593Smuzhiyun*volatile* come una variabile atomica di facile utilizzo, ma non è così.
16*4882a593SmuzhiyunL'uso di *volatile* nel kernel non è quasi mai corretto; questo documento ne
17*4882a593Smuzhiyundescrive le ragioni.
18*4882a593Smuzhiyun
19*4882a593SmuzhiyunIl punto chiave da capire su *volatile* è che il suo scopo è quello di
20*4882a593Smuzhiyunsopprimere le ottimizzazioni, che non è quasi mai quello che si vuole.
21*4882a593SmuzhiyunNel kernel si devono proteggere le strutture dati condivise contro accessi
22*4882a593Smuzhiyunconcorrenti e indesiderati: questa è un'attività completamente diversa.
23*4882a593SmuzhiyunIl processo di protezione contro gli accessi concorrenti indesiderati eviterà
24*4882a593Smuzhiyunanche la maggior parte dei problemi relativi all'ottimizzazione in modo più
25*4882a593Smuzhiyunefficiente.
26*4882a593Smuzhiyun
27*4882a593SmuzhiyunCome *volatile*, le primitive del kernel che rendono sicuro l'accesso ai dati
28*4882a593Smuzhiyun(spinlock, mutex, barriere di sincronizzazione, ecc) sono progettate per
29*4882a593Smuzhiyunprevenire le ottimizzazioni indesiderate.  Se vengono usate opportunamente,
30*4882a593Smuzhiyunnon ci sarà bisogno di utilizzare *volatile*.  Se vi sembra che *volatile* sia
31*4882a593Smuzhiyuncomunque necessario, ci dev'essere quasi sicuramente un baco da qualche parte.
32*4882a593SmuzhiyunIn un pezzo di codice kernel scritto a dovere, *volatile* può solo servire a
33*4882a593Smuzhiyunrallentare le cose.
34*4882a593Smuzhiyun
35*4882a593SmuzhiyunConsiderate questo tipico blocco di codice kernel::
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun    spin_lock(&the_lock);
38*4882a593Smuzhiyun    do_something_on(&shared_data);
39*4882a593Smuzhiyun    do_something_else_with(&shared_data);
40*4882a593Smuzhiyun    spin_unlock(&the_lock);
41*4882a593Smuzhiyun
42*4882a593SmuzhiyunSe tutto il codice seguisse le regole di sincronizzazione, il valore di un
43*4882a593Smuzhiyundato condiviso non potrebbe cambiare inaspettatamente mentre si trattiene un
44*4882a593Smuzhiyunlock.  Un qualsiasi altro blocco di codice che vorrà usare quel dato rimarrà
45*4882a593Smuzhiyunin attesa del lock.  Gli spinlock agiscono come barriere di sincronizzazione
46*4882a593Smuzhiyun- sono stati esplicitamente scritti per agire così - il che significa che gli
47*4882a593Smuzhiyunaccessi al dato condiviso non saranno ottimizzati.  Quindi il compilatore
48*4882a593Smuzhiyunpotrebbe pensare di sapere cosa ci sarà nel dato condiviso ma la chiamata
49*4882a593Smuzhiyunspin_lock(), che agisce come una barriera di sincronizzazione, gli imporrà di
50*4882a593Smuzhiyundimenticarsi tutto ciò che sapeva su di esso.
51*4882a593Smuzhiyun
52*4882a593SmuzhiyunSe il dato condiviso fosse stato dichiarato come *volatile*, la
53*4882a593Smuzhiyunsincronizzazione rimarrebbe comunque necessaria.  Ma verrà impedito al
54*4882a593Smuzhiyuncompilatore di ottimizzare gli accessi al dato anche _dentro_ alla sezione
55*4882a593Smuzhiyuncritica, dove sappiamo che in realtà nessun altro può accedervi.  Mentre si
56*4882a593Smuzhiyuntrattiene un lock, il dato condiviso non è *volatile*.  Quando si ha a che
57*4882a593Smuzhiyunfare con dei dati condivisi, un'opportuna sincronizzazione rende inutile
58*4882a593Smuzhiyunl'uso di *volatile* - anzi potenzialmente dannoso.
59*4882a593Smuzhiyun
60*4882a593SmuzhiyunL'uso di *volatile* fu originalmente pensato per l'accesso ai registri di I/O
61*4882a593Smuzhiyunmappati in memoria.  All'interno del kernel, l'accesso ai registri, dovrebbe
62*4882a593Smuzhiyunessere protetto dai lock, ma si potrebbe anche desiderare che il compilatore
63*4882a593Smuzhiyunnon "ottimizzi" l'accesso ai registri all'interno di una sezione critica.
64*4882a593SmuzhiyunMa, all'interno del kernel, l'accesso alla memoria di I/O viene sempre fatto
65*4882a593Smuzhiyunattraverso funzioni d'accesso; accedere alla memoria di I/O direttamente
66*4882a593Smuzhiyuncon i puntatori è sconsigliato e non funziona su tutte le architetture.
67*4882a593SmuzhiyunQueste funzioni d'accesso sono scritte per evitare ottimizzazioni indesiderate,
68*4882a593Smuzhiyunquindi, di nuovo, *volatile* è inutile.
69*4882a593Smuzhiyun
70*4882a593SmuzhiyunUn'altra situazione dove qualcuno potrebbe essere tentato dall'uso di
71*4882a593Smuzhiyun*volatile*, è nel caso in cui il processore è in un'attesa attiva sul valore
72*4882a593Smuzhiyundi una variabile.  Il modo giusto di fare questo tipo di attesa è il seguente::
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun    while (my_variable != what_i_want)
75*4882a593Smuzhiyun        cpu_relax();
76*4882a593Smuzhiyun
77*4882a593SmuzhiyunLa chiamata cpu_relax() può ridurre il consumo di energia del processore
78*4882a593Smuzhiyuno cedere il passo ad un processore hyperthreaded gemello; funziona anche come
79*4882a593Smuzhiyununa barriera per il compilatore, quindi, ancora una volta, *volatile* non è
80*4882a593Smuzhiyunnecessario.  Ovviamente, tanto per puntualizzare, le attese attive sono
81*4882a593Smuzhiyungeneralmente un atto antisociale.
82*4882a593Smuzhiyun
83*4882a593SmuzhiyunCi sono comunque alcune rare situazioni dove l'uso di *volatile* nel kernel
84*4882a593Smuzhiyunha senso:
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun  - Le funzioni d'accesso sopracitate potrebbero usare *volatile* su quelle
87*4882a593Smuzhiyun    architetture che supportano l'accesso diretto alla memoria di I/O.
88*4882a593Smuzhiyun    In pratica, ogni chiamata ad una funzione d'accesso diventa una piccola
89*4882a593Smuzhiyun    sezione critica a se stante, e garantisce che l'accesso avvenga secondo
90*4882a593Smuzhiyun    le aspettative del programmatore.
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun  - I codice *inline assembly* che fa cambiamenti nella memoria, ma che non
93*4882a593Smuzhiyun    ha altri effetti espliciti, rischia di essere rimosso da GCC.  Aggiungere
94*4882a593Smuzhiyun    la parola chiave *volatile* a questo codice ne previene la rimozione.
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun  - La variabile jiffies è speciale in quanto assume un valore diverso ogni
97*4882a593Smuzhiyun    volta che viene letta ma può essere lette senza alcuna sincronizzazione.
98*4882a593Smuzhiyun    Quindi jiffies può essere *volatile*, ma l'aggiunta ad altre variabili di
99*4882a593Smuzhiyun    questo è sconsigliata.  Jiffies è considerata uno "stupido retaggio"
100*4882a593Smuzhiyun    (parole di Linus) in questo contesto; correggerla non ne varrebbe la pena e
101*4882a593Smuzhiyun    causerebbe più problemi.
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun  - I puntatori a delle strutture dati in una memoria coerente che potrebbe
104*4882a593Smuzhiyun    essere modificata da dispositivi di I/O può, a volte, essere legittimamente
105*4882a593Smuzhiyun    *volatile*.  Un esempio pratico può essere quello di un adattatore di rete
106*4882a593Smuzhiyun    che utilizza un puntatore ad un buffer circolare, questo viene cambiato
107*4882a593Smuzhiyun    dall'adattatore per indicare quali descrittori sono stati processati.
108*4882a593Smuzhiyun
109*4882a593SmuzhiyunPer la maggior parte del codice, nessuna delle giustificazioni sopracitate può
110*4882a593Smuzhiyunessere considerata.  Di conseguenza, l'uso di *volatile* è probabile che venga
111*4882a593Smuzhiyunvisto come un baco e porterà a verifiche aggiuntive.  Gli sviluppatori tentati
112*4882a593Smuzhiyundall'uso di *volatile* dovrebbero fermarsi e pensare a cosa vogliono davvero
113*4882a593Smuzhiyunottenere.
114*4882a593Smuzhiyun
115*4882a593SmuzhiyunLe modifiche che rimuovono variabili *volatile* sono generalmente ben accette
116*4882a593Smuzhiyun- purché accompagnate da una giustificazione che dimostri che i problemi di
117*4882a593Smuzhiyunconcorrenza siano stati opportunamente considerati.
118*4882a593Smuzhiyun
119*4882a593SmuzhiyunRiferimenti
120*4882a593Smuzhiyun===========
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun[1] http://lwn.net/Articles/233481/
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun[2] http://lwn.net/Articles/233482/
125*4882a593Smuzhiyun
126*4882a593SmuzhiyunCrediti
127*4882a593Smuzhiyun=======
128*4882a593Smuzhiyun
129*4882a593SmuzhiyunImpulso e ricerca originale di Randy Dunlap
130*4882a593Smuzhiyun
131*4882a593SmuzhiyunScritto da Jonathan Corbet
132*4882a593Smuzhiyun
133*4882a593SmuzhiyunMigliorato dai commenti di Satyam Sharma, Johannes Stezenbach, Jesper
134*4882a593SmuzhiyunJuhl, Heikki Orsila, H. Peter Anvin, Philipp Hahn, e Stefan Richter.
135