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  

#include

#include  

 

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日出版

你可能感兴趣的:(Linux内核同步机制API函数:宏:spin_lock_init ( ))