在中找到该代码_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
,但它仍然保持原样,以阐明比较的意图(即,将递增的先前值与测试值进行比较)。
还是哇 答案似乎是:为了清楚和代码一致。