พบรหัสใน_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 คำตอบดูเหมือนจะเป็น: เพื่อความชัดเจนและความสอดคล้องของรหัส