다른 사람이 잠금을 얻으려고 할 때 _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
, 그것은 비교의 의미를 명확히하기 위해, 그대로 남아있는 (예. 테스트 값으로 증가 이전 값을 비교).
아니면 야 대답은 명확하고 코드 일관성을 유지하는 것으로 보입니다.