c++ - license - ¿Qué significa la instrucción "lock" en el ensamble x86?
qt offline installer (3)
Desde google, sabía que la instrucción de bloqueo provocaría que la CPU bloqueara el bus, pero no sé cuándo la CPU liberará el bus.
LOCK
es un prefijo de instrucción, por lo tanto, solo se aplica a la siguiente instrucción, la fuente no lo deja muy claro aquí, pero la instrucción real es LOCK INC
. Entonces el Bus está bloqueado por el incremento, luego se desbloquea
Sobre todo el código anterior, no entiendo cómo estos códigos implementaron el Add?
No implementan un Add, implementan un incremento, junto con una indicación de retorno si el valor anterior era 0. Una adición usaría LOCK XADD
(sin embargo, Windows InterlockedIncrement / Decrement también se implementa con LOCK XADD
).
Vi un ensamblaje x86 en la fuente de Qt:
q_atomic_increment:
movl 4(%esp), %ecx
lock
incl (%ecx)
mov $0,%eax
setne %al
ret
.align 4,0x90
.type q_atomic_increment,@function
.size q_atomic_increment,.-q_atomic_increment
De Google, sabía
lock
instrucción delock
hará que la CPU bloquee el bus, pero no sé cuándo la CPU libera el bus.Sobre todo el código anterior, no entiendo cómo este código implementa el
Add
?
LOCK
no es una instrucción en sí misma: es un prefijo de instrucción, que se aplica a las siguientes instrucciones. Esa instrucción debe ser algo que haga una lectura-modificación-escritura en la memoria (INC
,XCHG
,CMPXCHG
, etc.) --- en este caso, es la instrucciónincl (%ecx)
que incluye la palabra lógica en la dirección retenida en el registroecx
.El prefijo
LOCK
garantiza que la CPU tenga la propiedad exclusiva de la línea de caché adecuada durante la operación y proporciona ciertas garantías de pedido adicionales. Esto se puede lograr afirmando un bloqueo de bus, pero la CPU evitará esto siempre que sea posible. Si el bus está bloqueado, es solo por la duración de la instrucción bloqueada.Este código copia la dirección de la variable a incrementar de la pila en el registro
ecx
, luegolock incl (%ecx)
para incrementar atómicamente esa variable en 1. Las siguientes dos instrucciones configuran el registroeax
(que contiene el valor de retorno) de la función) a 0 si el nuevo valor de la variable es 0, y 1 de lo contrario. La operación es un incremento , no un complemento (de ahí el nombre).
Lo que puede estar fallando en entender es que el microcódigo requerido para incrementar un valor requiere que primero leamos en el valor anterior.
La palabra clave Lock obliga a las múltiples microinstrucciones que en realidad aparecen a operar atómicamente.
Si tenía 2 hilos cada uno tratando de incrementar la misma variable, y ambos leen el mismo valor original al mismo tiempo, ambos aumentan al mismo valor, y ambos escriben el mismo valor.
En lugar de tener la variable incrementada dos veces, que es la expectativa típica, terminas incrementando la variable una vez.
La palabra clave de bloqueo evita que esto suceda.