分析Linux中Spinlock在ARM及X86平臺上的實現(xiàn)
本文主要以2.6.22.6內(nèi)核分析Linux中spinlock在ARM及X86平臺上的實現(xiàn)(不同版本的內(nèi)核實現(xiàn)形式會有一些差異,但原理大致相同)。此處默認大家已經(jīng)熟悉了spinlock的使用,重點解釋容易引起迷惑的體系結(jié)構(gòu)相關(guān)的實現(xiàn)部分。
一、spin_lock(lock)的實現(xiàn)
/***include/linux/spinlock.h中***/
#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
//如果配置了SMP或配置自旋鎖調(diào)試功能
# include linux/spinlock_api_smp.h>
#else //如果是單處理器且不配置自旋鎖調(diào)試功能
# include linux/spinlock_api_up.h>
#endif
……
#define spin_lock(lock) _spin_lock(lock)
1、如果是單處理器
/****include/linux/spinlock_api_up.h****/
#define _spin_lock(lock) __LOCK(lock)
#define __LOCK(lock)
do { preempt_disable(); __acquire(lock); (void)(lock); } while (0)
?。?)preempt_disable():禁止搶占
?。?)__acquire(lock):在include/linux/compiler.h中有定義
#ifdef __CHECKER__
……
# define __acquire(x) __context__(x,1)
# define __release(x) __context__(x,-1)
#else
……
# define __acquires(x)
# define __releases(x)
這是一對用于sparse對代碼檢測的相互關(guān)聯(lián)的函數(shù)定義,第一句表示要增加變量x的計數(shù),增加量為1,第二句則正好相反,這個是用來函數(shù)編譯的過程中。如果在代碼中出現(xiàn)了不平衡的狀況,那么在Sparse的檢測中就會報警。如果要使用Sparse檢測功能就需要安裝sparse工具(參考相關(guān)安裝方法),然后編譯內(nèi)核
#make zImage C=1 (C=1,只檢測新編譯的文件,C=2是查所有文件)
Sparse會定義__CHECKER__,如果你沒有使用sparse工具,__acquire(lock)則定義為空
?。?)(void)(lock):通過插入一個變量本身的求值表達式,使編譯器不再報警,如:“variable 'lock' is defined but never used”。這種求值不會影響運行時的速度。
2、如果配置了SMP
/****include/linux/spinlock_api_smp.h中****/
void __lockfunc _spin_lock(spinlock_t *lock) __acquires(lock);
/***kernel/spinlock.c***/
void __lockfunc _spin_lock(spinlock_t *lock)
{
preempt_disable();
//關(guān)閉搶占
spin_acquire(lock->dep_map, 0, 0, _RET_IP_);
//自旋鎖調(diào)試用,在沒有定義自旋鎖調(diào)試的時候是空函數(shù)
_raw_spin_lock(lock);
}
/***include/linux/spinlock.h***/
#ifdef CONFIG_DEBUG_SPINLOCK
extern void _raw_spin_lock(spinlock_t *lock);//在lib/spinlock_debug.c中實現(xiàn)
#else //smp情況
# define _raw_spin_lock(lock) __raw_spin_lock((lock)->raw_lock)
3、__raw_spin_lock在ARM處理器上的實現(xiàn)
/******include/asm-arm/spinlock_types.h***/
typedef struct {
volatile unsigned int lock;
} raw_spinlock_t;
#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
/******include/asm-arm/spinlock.h***/
#if __LINUX_ARM_ARCH__ 6
#error SMP not supported on pre-ARMv6 CPUs //ARMv6后,才有多核ARM處理器
#endif
……
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)
評論