宏定义:
在内核源码中的位置: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日出版