Linux內核同步機制API函數:宏:spin_lock_init ( )

宏定義:

      在內核源碼中的位置: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日出版

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章