다른 사람이 잠금을 얻으려고 할 때 _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은 AS 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)이 if인지 확인하는 것과 일치하는지 확인하면 다음 value + 1 == SPINLOCK_SHARED | 1과 같이 다시 작성할 수 있습니다.value == (SPINLOCK_SHARED | 1) - 1 (이것은 그 동안 아무것도 변경되지 않은 경우)
동안 value == (SPINLOCK_SHARED | 1) - 1으로 다시 작성할 수 있습니다 value == SPINLOCK_SHARED, 그것은 비교의 의미를 명확히하기 위해, 그대로 남아있는 (예. 테스트 값으로 증가 이전 값을 비교).
아니면 야 대답은 명확하고 코드 일관성을 유지하는 것으로 보입니다.