在中找到该代码_spin_lock_contested,_spin_lock_quick当其他人尝试获取该锁时调用该代码:
count = atomic_fetchadd_int(&spin->counta, 1);
if (__predict_false(count != 0)) {
_spin_lock_contested(spin, ident, count);
}
如果没有比赛,则count(先前的值)应该为0,但不是。该count值作为参数传递给_spin_lock_contested作为value参数。这value然后与检查if从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;
}
请记住,这value是的前一个值spin->counta,而后者已经增加了1,我们希望spin->counta等于value + 1(除非与此同时有所变化)。
因此,检查spin->counta == SPINLOCK_SHARED | 1(的前提atomic_cmpset_int)是否对应于检查是否value + 1 == SPINLOCK_SHARED | 1可以重写为value == (SPINLOCK_SHARED | 1) - 1(同样,如果在此期间没有任何更改)。
尽管value == (SPINLOCK_SHARED | 1) - 1可以改写为value == SPINLOCK_SHARED,但它仍然保持原样,以阐明比较的意图(即,将递增的先前值与测试值进行比较)。
还是哇 答案似乎是:为了清楚和代码一致。