Vous pouvez également envisager ce à partir du Noyau Linux Documentation.
C programmeurs ont souvent pris des volatiles à dire que la variable peut être
modifié en dehors du thread en cours d'exécution; en conséquence, ils sont
parfois tentés de l'utiliser dans le code du noyau quand on le partage des structures de données sont
utilisé. En d'autres termes, ils ont été connus pour traiter les types de volatiles
comme une sorte de simple variable atomique, qu'ils ne le sont pas. L'utilisation de la volatilité dans
le code du noyau est presque jamais correcte, ce document explique pourquoi.
Le point essentiel à comprendre à l'égard de la volatilité, c'est que son but est
pour supprimer l'optimisation, ce qui n'est presque jamais ce qu'on veut vraiment
n'. Dans le noyau, il convient de protéger les données partagée des structures contre
indésirables d'accès simultanés, ce qui est très bien une tâche différente. L'
procédure de protection contre les simultanéité permettra également d'éviter presque
tous les problèmes d'optimisation d'une façon plus efficace.
Comme volatile, le noyau primitives qui rendent l'accès simultané aux données
coffre-fort (spinlocks, mutex, les barrières de la mémoire, etc.) sont conçus pour empêcher
indésirables d'optimisation. Si elles sont utilisées correctement, il n'y aura pas
besoin d'utiliser volatile. Si volatile est toujours nécessaire, il est
presque certainement un bug dans le code quelque part. Correctement écrit noyau
code, la volatilité ne peut que ralentir les choses.
Prenons le cas typique de bloc de code du noyau:
spin_lock(&the_lock);
do_something_on(&shared_data);
do_something_else_with(&shared_data);
spin_unlock(&the_lock);
Si tout le code qui suit le verrouillage des règles, la valeur de shared_data ne peut pas
changer de manière inattendue alors the_lock est tenue. Tout autre code qui pourrait
envie de jouer avec les données seront en attente sur la serrure. Le spinlock
primitives agissent comme des barrières de la mémoire - s'ils sont explicitement écrit pour le faire
ce qui signifie que des données d'accès ne sera pas optimisé à travers eux. De sorte que le
compilateur pourrait penser qu'il sait ce qui va être dans shared_data, mais l'
spin_lock() l'appel, puisqu'il agit comme une barrière de mémoire, va l'obliger à
oubliez tout ce qu'il sait. Il n'y aura pas de problèmes d'optimisation avec
accède à ces données.
Si shared_data ont été déclarées volatile, le blocage serait encore
nécessaire. Mais le compilateur pourrait également être empêché de l'optimisation de l'accès
pour shared_data au sein de la section critique, quand on sait que personne d'autre ne
peut travailler avec elle. Alors que le verrou est détenu, shared_data n'est pas
volatile. Lorsque vous traitez avec des données partagées, bon verrouillage rend volatile
inutile et potentiellement dangereux.
La volatilité de la classe de stockage était destiné à l'origine pour memory-mapped I/O
les registres. Dans le noyau, le registre accède, elle aussi, doit être protégé
par les verrous, mais on ne veut pas que le compilateur "l'optimisation" enregistrer
accède à l'intérieur d'une section critique. Mais, dans le noyau, la mémoire des e/S
les accès sont toujours fait par le biais de fonctions d'accesseur; un accès à une mémoire des e/S
directement par le biais de pointeurs, c'est mal vu et ne fonctionne pas sur tous les
architectures. Ces accesseurs sont écrits pour éviter les
d'optimisation, de sorte que, une fois de plus, la volatilité est inutile.
Une autre situation où l'on pourrait être tenté d'utiliser le volatile est
lorsque le processeur est occupé-en attente sur la valeur d'une variable. Le droit
pour effectuer une attente active est:
while (my_variable != what_i_want)
cpu_relax();
Le cpu_relax() l'appel peut réduire la consommation du PROCESSEUR ou de céder à un
hyperthread twin processeur; il arrive aussi de servir de barrière de mémoire,
donc, une fois de plus, la volatilité est inutile. Bien sûr, occupé-attendre, est
généralement, un anti-sociale, loi sur pour commencer.
Il y a encore quelques rares cas où les volatiles de sens que dans la
noyau:
Le ci-dessus mentionné fonctions d'accesseur peut utiliser volatile sur
les architectures où direct I/O accès à la mémoire fonctionne. Essentiellement,
chaque accesseur appel devient un peu de la section critique sur son propre et
s'assure que l'accès se passe comme prévu par le programmeur.
Assembly en ligne de code qui change de la mémoire, mais qui n'a pas d'autres
visible effets secondaires, risque d'être supprimé par la GCC. L'ajout de la volatilité de l'
mot-clé à l'asm, les déclarations d'empêcher cette suppression.
Le jiffies variable est particulière en ce qu'elle peut avoir une valeur différente
chaque fois qu'il est référencé, mais il peut être lu sans
verrouillage. Donc jiffies peut être volatile, mais l'ajout d'autres
les variables de ce type est fortement désapprouvée. Jiffies est considéré comme
pour être un "stupide héritage" (Linus de mots) à cet égard; en le fixant
serait plus d'ennuis que cela vaut la peine.
Des pointeurs vers des structures de données cohérente de la mémoire qui sont susceptibles d'être modifiés
par des périphériques d'e/S peuvent, parfois, être légitimement volatile. Un anneau de la mémoire tampon
utilisé par une carte réseau, où que l'adaptateur change de pointeurs vers
indiquer les descripteurs ont été traitées, est un exemple de ce
type de situation.
Pour la plupart de code, aucune de ces justifications, le volatile s'appliquent. En tant que
résultat, l'utilisation de la volatilité est susceptible d'être considérée comme un bug et apportera
un examen plus approfondi du code. Les développeurs qui sont tentés d'utiliser des
volatile devrait prendre du recul et de réfléchir à ce qu'ils sont vraiment à essayer
pour accomplir.