El código se encuentra en _spin_lock_contested
, que se llama _spin_lock_quick
cuando alguien más intenta obtener el bloqueo:
count = atomic_fetchadd_int(&spin->counta, 1);
if (__predict_false(count != 0)) {
_spin_lock_contested(spin, ident, count);
}
Si no hay concurso, entonces count
(el valor anterior) debería serlo 0
, pero no lo es. Este count
valor se pasa como parámetro a _spin_lock_contested
como value
parámetro. Esto value
luego se verifica con if
el OP:
/*
* WARNING! Caller has already incremented the lock. We must
* increment the count value (from the inline's fetch-add)
* to match.
*
* Handle the degenerate case where the spinlock is flagged SHARED
* with only our reference. We can convert it to EXCLUSIVE.
*/
if (value == (SPINLOCK_SHARED | 1) - 1) {
if (atomic_cmpset_int(&spin->counta, SPINLOCK_SHARED | 1, 1))
return;
}
Teniendo en cuenta que ese value
es el valor anterior de spin->counta
, y este último ya se ha incrementado en 1, esperamos spin->counta
que sea igual value + 1
(a menos que algo haya cambiado mientras tanto).
Por lo tanto, verificar si spin->counta == SPINLOCK_SHARED | 1
(la condición previa de atomic_cmpset_int
) corresponde a verificar si value + 1 == SPINLOCK_SHARED | 1
, que puede reescribirse como value == (SPINLOCK_SHARED | 1) - 1
(nuevamente, si nada ha cambiado mientras tanto).
Si bien value == (SPINLOCK_SHARED | 1) - 1
podría reescribirse como value == SPINLOCK_SHARED
, se deja como está, para aclarar la intención de la comparación (es decir, comparar el valor anterior incrementado con el valor de la prueba).
O iow. la respuesta parece ser: por claridad y consistencia del código.