宏定義:
在內核源碼中的位置:linux-2.6.30/include/linux/spinlock.h
宏定義格式:# define spin_lock_init(lock) \
do { *(lock) = SPIN_LOCK_UNLOCKED; } while (0)
宏功能描述:
宏spin_lock_init( ):初始化自旋鎖lock,其實是將自旋鎖指針lock 指向SPIN_LOCK_UNLOCKED宏,該宏的定義在內核文件linux-2.6.30/include/linux/spinlock_types.h中,它表示自旋鎖的狀態爲未加鎖。
輸入參數說明:
lock:指向自旋鎖結構體的一個指針,自旋鎖結構體spinlock_t 在內核文件linux-2.6.30/include/linux/spinlock_types.h中定義:
typedef struct {
raw_spinlock_t raw_lock;
#ifdef CONFIG_GENERIC_LOCKBREAK
unsigned int break_lock;
#endif
#ifdef CONFIG_DEBUG_SPINLOCK
unsigned int magic, owner_cpu;
void *owner;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
} spinlock_t;
在結構體spinlock_t中,主要成員是raw_spinlock_t 類型的raw_lock,自旋鎖的操作主要作用於raw_spinlock_t 類型的slock整型字段上,下面給出了結構體raw_spinlock_t的定義,它存在於文件linux-2.6.30/arch/x86/include/asm/spinlock_types.h文件中。
typedef struct raw_spinlock {
unsigned int slock;
} raw_spinlock_t;
實例解析:
編寫測試文件:spin_lock_init.c
#include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int __init spin_lock_init_init(void);
static void __exit spin_lock_init_exit(void);
spinlock_t lock = SPIN_LOCK_UNLOCKED;
nt __init spin_lock_init_init(void)
{
/*輸出宏SPIN_LOCK_UNLOCKED的相關信息*/
printk("<0>SPIN_LOCK_UNLOCKED: %d\n",SPIN_LOCK_UNLOCKED.raw_lock.slock);
spin_lock_init( &lock ); //初始化自旋鎖
printk("<0>after init, slock: %d\n",lock.raw_lock.slock);
printk("<0>\n");
spin_lock( &lock ); //第一次獲取自旋鎖
printk("<0>first spin_lock, slock: %d\n",lock.raw_lock.slock);
spin_unlock( &lock ); //第一次釋放自旋鎖
printk("<0>first spin_unlock, slock: %d\n",lock.raw_lock.slock);
printk("<0>\n");
spin_lock( &lock ); //第二次獲取自旋鎖
printk("<0>second spin_lock, slock: %d\n",lock.raw_lock.slock);
spin_unlock( &lock ); //第二次釋放自旋鎖
printk("<0>second spin_unlock, slock: %d\n",lock.raw_lock.slock);
return 0;
}
void __exit spin_lock_init_exit(void)
{
printk("<0>exit!\n");
}
module_init(spin_lock_init_init);
module_exit(spin_lock_init_exit);
實例運行結果及分析:
首先編譯模塊,執行命令insmod spin_lock_init.ko 插入模塊,然後執行命令dmesg –c,會出現如圖8.40所示的結果:
結果分析:
測試程序中調用了宏spin_lock( )和宏spin_unlock( ),分別用來獲取和釋放自旋鎖,關於其功能見本章中關於它們的分析。
測試程序中,首先輸出宏SPIN_LOCK_UNLOCKED的信息,它所表示的自旋鎖的狀態爲未使用。調用宏spin_lock_init( )初始化自旋鎖lock,結構體raw_spinlock_t中的slock字段被置爲0,即 Owner 和 Next 爲 0。然後第一次執行獲取和釋放鎖的操作,調用spin_lock( )後,slock字段爲256,16進製爲0x0100,即Next 域進行了加1操作;調用spin_unlock( ),slock字段爲0x0101,此時Owner域也進行了加1 操作,二者相等,鎖處於未使用狀態。第二次獲取和釋放鎖時,slock字段分別爲0x0201和0x0202,可以看到線程是按照申請順序依次獲取排隊自旋鎖的。
如果一個自旋鎖持有者在釋放鎖之前,另一個線程想要申請鎖,則它會檢測到鎖的狀態爲正在被使用(因爲鎖未釋放前Next域和Owner域不相等),從而進入忙等待。
本文出自:《Linux內核API完全參考手冊》邱鐵,周玉,鄧瑩瑩 編著,機械工業出版社 2011年1月1日出版