Il codice si trova in _spin_lock_contested
, che viene chiamato da _spin_lock_quick
quando qualcun altro sta tentando di ottenere il blocco:
count = atomic_fetchadd_int(&spin->counta, 1);
if (__predict_false(count != 0)) {
_spin_lock_contested(spin, ident, count);
}
Se non ci sono contest, allora count
(il valore precedente) dovrebbe essere 0
, ma non lo è. Questo count
valore viene passato come parametro a _spin_lock_contested
come value
parametro. Questo value
viene quindi verificato con if
dall'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;
}
Tenendo presente che value
è il valore precedente di spin->counta
, e quest'ultimo è già stato incrementato di 1, ci aspettiamo spin->counta
che sia uguale value + 1
(a meno che qualcosa non sia cambiato nel frattempo).
Quindi, verificare se spin->counta == SPINLOCK_SHARED | 1
(la condizione preliminare di atomic_cmpset_int
) corrisponde a verificare se value + 1 == SPINLOCK_SHARED | 1
, che può essere riscritto come value == (SPINLOCK_SHARED | 1) - 1
(di nuovo, se nel frattempo non è cambiato nulla).
Mentre value == (SPINLOCK_SHARED | 1) - 1
potrebbe essere riscritto come value == SPINLOCK_SHARED
, è lasciato così com'è, per chiarire l'intento del confronto (cioè per confrontare il valore precedente incrementato con il valore del test).
O iow. la risposta sembra essere: per chiarezza e coerenza del codice.