Kodunuz eşittir: Sen kodundan görebilirsiniz
static __inline__ int xchg_asm(int* lock, int val) {
int save_old_value_at_eax;
save_old_value_at_eax = *lock; /* with a wrong lock prefix */
xchg *lock with val and discard the original value of *lock.
return save_old_value_at_eax; /* but it not the real original value of *lock */
}
, save_old_value_at_eax
hiçbir cpu xchg yaparken gerçek orijinal değerdir. Eski/orijinal değeri xchg yönergesiyle almalı, xchg'u gerçekleştirmeden önce kaydetmelisiniz. ("gerçek eski/orjinal değer değil" anlamına gelir, eğer başka bir CPU kilidi saklarsa bu CPU değeri kaydeder ama bu CPU xchg komutunu gerçekleştirmeden önce, bu CPU yanlış eski değeri alır ve kilit başarılı, böylece iki CPU aynı anda CS'ye girer). Bir okuma-değiştirme-yazma talimatını üç talimata ayırdınız, üç talimatın tümü atomik değildir (kilit önekini xchg'ye taşımanız bile).
Sana kilit önek BÜTÜN üç talimatları kilitlenir, ama aslında kilit önek yalnızca bağlı olduğu tek talimat (bütün talimatlar eklenebilir değil) için kullanılabilecek düşünce tahmin Ve biz değiliz xchg için SMP üzerinde kilit önekine ihtiyacınız var. linux_kernel_src/kemer alıntı/x86 ///asm/cmpxchg.h
/*
* Note: no "lock" prefix even on SMP: xchg always implies lock anyway.
* Since this is generally used to protect other memory information, we
* use "asm volatile" and "memory" clobbers to prevent gcc from moving
* information around.
*/
Benim önerileri şunlardır:
- KENDİNİZİ TEKRAR YAPMAYIN, linux çekirdeğinin döndürme kilit kullanın.
- KENDİNİZİ TEKRARLAMAYIN, eğer bir döndürme kilidi uygulamak istiyorsanız, lütfen linux çekirdeğin xchg(), cmpxchg() öğesini kullanın.
- Yönergeler hakkında daha fazla bilgi edinin. Linux çekirdeğinin nasıl uygulandığını da öğrenebilirsiniz.
Eklemem yukarıda. –
Mükemmel; Muhtemelen hata değil, spin_destroy() işleviyle, spin_init() 'tarafından tahsis edilmeyen belleği boşaltmak benim için çok garip görünüyor. (Ayrıca bir 'spin_alloc()' işlevi var mı?) – sarnold
spin_destory fazla olabilir. –