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