Kode ditemukan di _spin_lock_contested
, yang dipanggil dari _spin_lock_quick
ketika orang lain berusaha mendapatkan kunci:
count = atomic_fetchadd_int(&spin->counta, 1);
if (__predict_false(count != 0)) {
_spin_lock_contested(spin, ident, count);
}
Jika tidak ada kontes, maka count
(nilai sebelumnya) seharusnya 0
, tetapi tidak. Ini count
nilai dilewatkan sebagai parameter untuk _spin_lock_contested
sebagai value
parameter. Ini value
kemudian diperiksa dengan if
dari 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;
}
Dengan mengingat bahwa itu value
adalah nilai sebelumnya spin->counta
, dan yang terakhir telah bertambah 1, kami berharap spin->counta
sama value + 1
(kecuali ada sesuatu yang berubah pada saat itu).
Jadi, memeriksa apakah spin->counta == SPINLOCK_SHARED | 1
(prasyarat atomic_cmpset_int
) sesuai dengan memeriksa jika value + 1 == SPINLOCK_SHARED | 1
, yang dapat ditulis ulang sebagai value == (SPINLOCK_SHARED | 1) - 1
(sekali lagi, jika tidak ada yang berubah pada saat itu).
Sementara value == (SPINLOCK_SHARED | 1) - 1
dapat ditulis ulang sebagaimana value == SPINLOCK_SHARED
, dibiarkan apa adanya, untuk memperjelas maksud perbandingan (mis. Untuk membandingkan nilai sebelumnya yang ditambahkan dengan nilai tes).
Atau iow. jawabannya adalah: untuk kejelasan dan konsistensi kode.