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