พบรหัสใน_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
มันเป็นซ้ายเพื่อชี้แจงความตั้งใจของการเปรียบเทียบ (เช่น. เพื่อเปรียบเทียบค่าที่เพิ่มขึ้นก่อนหน้านี้กับค่าทดสอบ)
หรือ iow คำตอบดูเหมือนจะเป็น: เพื่อความชัดเจนและความสอดคล้องของรหัส