O código é encontrado em _spin_lock_contested
, que é chamado _spin_lock_quick
quando outra pessoa está tentando obter o bloqueio:
count = atomic_fetchadd_int(&spin->counta, 1);
if (__predict_false(count != 0)) {
_spin_lock_contested(spin, ident, count);
}
Se não houver concurso, count
o valor anterior deve ser 0
, mas não é. Este count
valor é passado como parâmetro para _spin_lock_contested
como o value
parâmetro. Isso value
é verificado com o if
do 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;
}
Tendo em mente que value
é o valor anterior de spin->counta
, e o último já foi incrementado em 1, esperamos spin->counta
ser iguais value + 1
(a menos que algo tenha mudado nesse meio tempo).
Portanto, verificar se spin->counta == SPINLOCK_SHARED | 1
(a pré-condição de atomic_cmpset_int
) corresponde a verificar se value + 1 == SPINLOCK_SHARED | 1
, que pode ser reescrito como value == (SPINLOCK_SHARED | 1) - 1
(novamente, se nada mudou nesse meio tempo).
Embora value == (SPINLOCK_SHARED | 1) - 1
possa ser reescrito como value == SPINLOCK_SHARED
, é deixado como está para esclarecer a intenção da comparação (ou seja, comparar o valor anterior incrementado com o valor do teste).
Ou uau. a resposta parece ser: para maior clareza e consistência do código.