কোডটি পাওয়া গেছে _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, তেমনি রেখে দেওয়া হয়েছে, তুলনার উদ্দেশ্যটি স্পষ্ট করার জন্য (যেমন পরীক্ষার মানের সাথে বর্ধিত পূর্ববর্তী মানটির তুলনা করা)।
বা iow। উত্তরটি প্রদর্শিত হবে: স্পষ্টতা এবং কোডের ধারাবাহিকতার জন্য।