Le code se trouve dans _spin_lock_contested, qui est appelé à partir du _spin_lock_quickmoment où quelqu'un d'autre tente d'obtenir le verrou:
count = atomic_fetchadd_int(&spin->counta, 1);
if (__predict_false(count != 0)) {
_spin_lock_contested(spin, ident, count);
}
S'il n'y a pas de concours, alors count(la valeur précédente) devrait l'être 0, mais ce n'est pas le cas. Cette countvaleur est transmise en tant que paramètre à en _spin_lock_contestedtant que valueparamètre. Ceci valueest ensuite vérifié avec ifl'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;
}
En gardant à l'esprit que valuec'est la valeur précédente de spin->counta, et que celle-ci a déjà été incrémentée de 1, nous nous attendons spin->countaà égaler value + 1(sauf si quelque chose a changé entre-temps).
Donc, vérifier si spin->counta == SPINLOCK_SHARED | 1(la condition préalable de atomic_cmpset_int) correspond à vérifier si value + 1 == SPINLOCK_SHARED | 1, qui peut être réécrit comme value == (SPINLOCK_SHARED | 1) - 1(encore une fois, si rien n'a changé entre-temps).
Bien qu'il value == (SPINLOCK_SHARED | 1) - 1puisse être réécrit tel value == SPINLOCK_SHAREDquel, il reste tel quel, pour clarifier l'intention de la comparaison (c'est-à-dire comparer la valeur précédente incrémentée avec la valeur de test).
Ou iow. la réponse semble être: pour la clarté et la cohérence du code.