Lire et écrire l'implémentation de l'opération atomique dans le noyau Linux
Récemment, j'ai jeté un coup d'oeil dans le noyau Linux de la mise en œuvre d'un atomic lire et à écrire et quelques questions.
D'abord, le code de l'architecture ia64:
typedef struct {
int counter;
} atomic_t;
#define atomic_read(v) (*(volatile int *)&(v)->counter)
#define atomic64_read(v) (*(volatile long *)&(v)->counter)
#define atomic_set(v,i) (((v)->counter) = (i))
#define atomic64_set(v,i) (((v)->counter) = (i))
- Pour les opérations de lecture et écriture, il semble que l'approche directe a été prise afin de lire ou d'écrire dans la variable. Sauf s'il y a un autre truc quelque part, je ne comprends pas quelles garanties existent que cette opération sera atomique dans le domaine de montage. Je crois qu'une réponse évidente sera qu'une telle opération se traduit par une assemblée opcode, mais tout de même, comment est garanti lors de la prise en compte de la mémoire différents niveaux de cache (ou d'autres optimisations)?
- Sur la lecture des macros, le volatile type est utilisé dans un casting truc. Quelqu'un a une idée de comment cela affecte l'atomicité ici? (Notez qu'il n'est pas utilisé dans l'opération d'écriture)
source d'informationauteur EdwardH | 2012-02-15
Vous devez vous connecter pour publier un commentaire.
Je pense que vous êtes mal à comprendre les (très vague) de l'utilisation du mot "atomique" et "volatile" ici. Atomique que vraiment signifie que les mots seront lus ou écrits automatiquement (en une seule étape, et de garantir que le contenu de ce mémoire sera toujours d'une écriture ou l'autre, et non quelque chose entre les deux). Et le
volatile
mot-clé indique au compilateur de ne jamais présumer que les données à cet endroit en raison d'une précédente lecture/écriture (en gros, ne jamais optimiser loin le lire).Ce que les mots "atomique" et "volatile" ne veux PAS dire ici est qu'il n'y a aucune forme de mémoire de synchronisation. Ne suppose AUCUNE lecture/écriture des barrières ou des clôtures. Rien n'est garanti en ce qui concerne la mémoire et de la cohérence de cache. Ces fonctions sont essentiellement atomique seulement au niveau des logiciels et du matériel peuvent optimiser/lie cependant il le juge bon.
Maintenant pourquoi tout simplement la lecture est assez: les modèles de mémoire pour chaque architecture sont différents. De nombreuses architectures peut garantir atomique lit ou écrit pour les données alignées pour un certain décalage d'octet, ou x de mots, etc. et varient d'un PROCESSEUR CPU. Le noyau Linux contient de nombreux définit pour les différentes architectures que de le laisser faire sans atomique appels (
CMPXCHG
essentiellement) sur des plates-formes de garantie (parfois même seulement dans la pratique, même si, en réalité, leur spécification dit la ne fait pas de garantie) atomique des lectures/écritures.Comme pour le
volatile
alors qu'il n'est pas nécessaire pour qu'il en général sauf si vous êtes accédant à la mémoire mappée IO, tout dépend de quand/où/pourquoi leatomic_read
etatomic_write
macros sont appelés. De nombreux compilateurs sera (même si elle n'est pas définie dans le C spec) générer les barrières de la mémoire/clôtures de la volatilité des variables (GCC, sur le dessus de ma tête, est un. MSVC fait pour vous.). Bien que cela ne normalement dire que tous des lectures/écritures de cette variable sont maintenant officiellement exemptés de tout les optimisations du compilateur, dans ce cas, par la création d'un "virtuel" volatile variable que cette instance particulière de lecture/écriture est hors-limites pour l'optimisation et de réorganisation.Les lectures sont atomiques sur la plupart des architectures, tant qu'ils sont alignés à un multiple de leur taille (et ne sont pas plus grand que la taille de lecture de donner le type), voir l'Architecture Intel manuels. Écrit d'autre part beaucoup de être différent, Intel précise que, selon x86, seul octet à écrire et aligné à l'écrit peut être atomique, en vertu de l'IPF (IA64), tout usage d'acquérir et de libération de la sémantique, ce qui serait garanti atomique, voir ceci.
la
volatile
empêche le compilateur de mise en cache de la valeur à l'échelle locale, en l'obligeant à récupérer à l'endroit où il y a accès.Si vous écrivez pour une architecture spécifique, vous pouvez faire des hypothèses spécifiques.
Je suppose IA-64 ne compiler ces choses en une seule instruction.
Le cache ne devrait pas être un problème, sauf si le compteur dépasse une ligne de cache boundry. Mais si 4/8 alignement d'octets est nécessaire, cela ne peut pas arriver.
Un "vrai" atomique instruction est requise lorsqu'une instruction machine, se traduit par deux accès à la mémoire. C'est le cas pour les incréments (lecture, l'accroissement, l'écriture) ou comparer&swap.
volatile
affecte les optimisations du compilateur peut faire.Par exemple, il empêche le compilateur à partir de la conversion de plusieurs lectures en une seule lecture.
Mais sur la machine niveau de l'instruction, il ne fait rien.