hai l'idea giusta, ma il vostro asm è rotto:
cmpxchg
non può funzionare con un operando immediato, registra solo.
lock
non è un prefisso valido per mov
. mov
a un indirizzo allineato è atomico su x86, quindi non è necessario lo lock
.
E 'stato un po' di tempo da quando ho usato AT & sintassi T, spero ricordava tutto:
spin_lock:
xorl %ecx, %ecx
incl %ecx
spin_lock_retry:
xorl %eax, %eax
lock; cmpxchgl %ecx, (lock_addr)
jnz spin_lock_retry
ret
spin_unlock:
movl $0 (lock_addr)
ret
Nota che GCC ha builtins atomiche, quindi in realtà non è necessario utilizzare asm inline per raggiungere questo obiettivo:
void spin_lock(int *p)
{
while(!__sync_bool_compare_and_swap(p, 0, 1));
}
void spin_unlock(int volatile *p)
{
asm volatile (""); // acts as a memory barrier.
*p = 0;
}
Come Bo dice qui di seguito, le istruzioni bloccati sostenere un costo: ognuno si utilizza deve svuotare la cache e bloccare bus di memoria del sistema, che può essere molto costoso se hai abbastanza CPU. Anche senza molte CPU, è ancora facile e vale la pena di ottimizzare in giro:
void spin_lock(int volatile *p)
{
while(!__sync_bool_compare_and_swap(p, 0, 1))
{
while(*p) _mm_pause();
}
}
L'istruzione pause
è di vitale importanza per le prestazioni su CPU HyperThreading quando hai il codice che gira in questo modo - permette il secondo thread di esecuzione mentre il primo thread sta girando. Nelle CPU che non supportano pause
, viene considerato come nop
.
caso il parametro per spin_lock void() anche essere dichiarato volatili? – ManRow
No. '__sync_bool_compare_and_swap' lo considera già come 'volatile'. –
L'asm usato come barriera di memoria all'interno di 'spin_unlock' dovrebbe probabilmente includere il clobber di memoria. D'altra parte, c'è '__sync_lock_release' che è progettato solo per fare la" barriera di scrittura e scrivere 0 "cosa senza dover pensare affatto a asm, ed è persino" un po 'portatile ". Non funziona esplicitamente come barriera di lettura (lo fa incidentalmente_ sull'architettura di destinazione), ma va bene. La cosa peggiore da fare è un altro thread che fa un singolo giro in più in un caso raro e improbabile. – Damon