2010-07-27 4 views
6

Je sais comment utiliser LOCK pour incrémenter threads en toute sécurité une valeur:Comment utiliser le préfixe LOCK ASM pour lire une valeur?

lock inc  [J]; 

Mais comment puis-je lire (ou toute valeur) [J] d'une manière thread-safe? Le préfixe LOCK ne peut pas être utilisé avec mov. Et si je fais ce qui suit:

xor eax, eax; 
    lock add eax, [J]; 
    mov [JC], eax; 

Il soulève une erreur sur la ligne 2.

+0

Qu'est-ce que vous essayez d'accomplir ici? – Iridium

+0

Tout ce que je veux faire est de lire [J] d'une manière sûre pour les threads. – IamIC

Répondre

9

Utilisez XADD ou instruction MOV place instruction ADD! Voir aussi MFENCE, LFENCE et SFENCE instructions!

EDIT: Vous ne pouvez pas utiliser l'instruction LOCK avec instruction ADD si l'opérande source est un opérande de mémoire!

De: « Intel® 64 et IA-32 ArchitecturesSoftware Manuel du développeur »

Le préfixe LOCK peut être préfixé que aux instructions suivantes et seulement à ces formes des instructions où l'opérande de destination est un opérande mémoire : ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG, CMPXCH8B, DEC, INC, NEG, PAS, OU, SBB, SUB, XOR, XADD, et XCHG. Si le préfixe LOCK est utilisé avec l'une de ces instructions et l'opérande de source est un opérande de mémoire, une exception d'opcode non définie (#UD) peut être générée . Une exception d'opcode non définie sera également générée si le préfixe LOCK est utilisé avec toute instruction ne figurant pas dans la liste ci-dessus. La instruction XCHG affirme toujours le signal LOCK # quelle que soit la présence ou l'absence du préfixe LOCK

EDIT2: Forme: "Intel® 64 et Manuel de l'IA-32 ArchitecturesSoftware Developer, Volume3A"

8.1.1 Opérations atomiques garanties. Le processeur Intel486 (et plus récents processeurs depuis) ​​garantit que les suivantes opérations de mémoire de base seront toujours effectués atomiquement:

  • lecture ou l'écriture d'un octet
  • lecture ou l'écriture d'un mot aligné sur un limite de 16 bits
  • lecture ou l'écriture d'un mot double aligné sur une limite de 32 bits

Le processeur Pentium (a nd nouveaux processeurs depuis) ​​garantit que les suite à des opérations de mémoire supplémentaires seront toujours effectués atomiquement:

  • lecture ou l'écriture d'un quadword aligné sur une limite
  • 6 bits 64 bits accède à la mémoire uncached emplacements qui correspondent à un bus de données 32 bits
    les processeurs de la famille P6
    (et plus récents processeurs depuis) ​​
    garantie que l'opération de mémoire supplémentaire
    suivant va
    toujours être effectuée de façon atomique:
  • Unaligned 16-, 32- et 64-bit a accès à la mémoire cache qui correspondent
    au sein d'une ligne de cache

accès à la mémoire qui sont cacheable fendu à travers largeurs de bus, les lignes de cache, et limites de la page ne sont pas garantis être atomique par le Intel Core 2 Duo, Intel Core Duo, Pentium M, Pentium 4, Intel Xeon, famille P6, Pentium et Intel486 processeurs. Le processeur Intel Core 2 Duo , Intel Core Duo, Pentium M, Pentium 4, processeurs Intel Xeon et P6 famille fournissent des signaux de commande de bus qui permettent des sous-systèmes de mémoire externe pour faire scission accès atomique; Toutefois, les accès aux données non alignés auront un impact sérieux sur les performances du processeur et doivent être évités.

Ainsi, pour la lecture que je prefare d'utiliser l'instruction CMPXCHG avec préfixe LOCK, comme:

LOCK  CMPXCHG EAX, [J] 

Pour writting:

MOV [J], EAX 
SFENSE 

.

+0

Le compilateur refuse de compiler la ligne 2. Même en le changeant en: xadd eax, dword ptr J; ne fonctionne pas. – IamIC

+0

Oui, la raison est que l'opérande source est un opérande de mémoire! –

+0

Merci pour la clarification sur pourquoi il ne compilerait pas. Donc il semble que je devrais soit utiliser les instructions de fencing, ou simplement faire un instantané de la valeur qui, étant en cours de traitement en lecture seule, ne devrait pas être un problème de sécurité du thread: mov eax, [ J]; mov [JSnapshot], eax; – IamIC

Questions connexes