Mã được tìm thấy _spin_lock_contested
, được gọi từ _spin_lock_quick
khi người khác đang cố lấy khóa:
count = atomic_fetchadd_int(&spin->counta, 1);
if (__predict_false(count != 0)) {
_spin_lock_contested(spin, ident, count);
}
Nếu không có cuộc thi, thì count
(giá trị trước đó) sẽ là 0
, nhưng không phải vậy. Đây count
giá trị được thông qua như là tham số để _spin_lock_contested
là value
tham số. Điều này value
sau đó được kiểm tra với if
từ 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;
}
Hãy nhớ rằng đó value
là giá trị trước đó và giá trị spin->counta
sau đã được tăng thêm 1, chúng tôi hy vọng spin->counta
sẽ bằng nhau value + 1
(trừ khi có gì đó đã thay đổi trong thời gian này).
Vì vậy, kiểm tra xem spin->counta == SPINLOCK_SHARED | 1
(điều kiện tiên quyết của atomic_cmpset_int
) tương ứng với việc kiểm tra xem value + 1 == SPINLOCK_SHARED | 1
, có thể được viết lại thành value == (SPINLOCK_SHARED | 1) - 1
(một lần nữa, nếu không có gì thay đổi trong thời gian đó).
Mặc dù value == (SPINLOCK_SHARED | 1) - 1
có thể được viết lại value == SPINLOCK_SHARED
, nhưng nó vẫn để làm rõ ý định so sánh (nghĩa là so sánh giá trị gia tăng trước đó với giá trị thử nghiệm).
Hoặc iow. câu trả lời dường như là: cho sự rõ ràng và thống nhất mã.