कोड में पाया जाता है _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
ओपी से जाँच की जाती है:
/*
* 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
, यह तुलना के इरादे को स्पष्ट करने के लिए (यानी, परीक्षण मूल्य के साथ संवर्धित पिछले मूल्य की तुलना करने के लिए) है।
या आईओडब्ल्यू। उत्तर प्रतीत होता है: स्पष्टता और कोड स्थिरता के लिए।