--为了获得一个自旋锁, 在某 CPU 上运行的代码需先执行一个原子操作,该操作测试并设置( test-and-set) 某个内存变量,由于它是原子操作,所以在该操作完成之前其他执行单元不可能访问这个内存变量。如果测试结果表明锁已经空闲,则程序获得这个自旋锁并继续执行;如果测试结果表明锁仍被占用,程序将在一个小的循环内重复这个“ 测试并设置” 操作,即进行所谓的“ 自旋”,通俗地说就是“在原地打转”。 |
使用范围:SMP或者单CPU但是内核可抢占
1.定义自旋锁 spinlock_t lock; 2.初始化自旋锁 spin_lock_init(lock) 该宏用于动态初始化自旋锁 lock。 3.获得自旋锁 spin_lock(lock) 该宏用于获得自旋锁 lock,如果能够立即获得锁,它就马上返回,否则,它将自旋在那里, 直到该自旋锁的保持者释放。 spin_trylock(lock) 该宏尝试获得自旋锁 lock,如果能立即获得锁,它获得锁并返回真,否则立即返回假,实际 上不再“在原地打转”。 4.释放自旋锁 spin_unlock(lock) |
使用程序模版
/* 定义一个自旋锁 spinlock_t lock; spin_lock_init(&lock); spin_lock (&lock) ; /* 获取自旋锁,保护临界区 */ . . ./* 临界区*/ spin_unlock (&lock) ; /* 解锁*/ |
成套自旋锁机制
spin_lock_irq() = spin_lock() + local_irq_disable() spin_unlock_irq() = spin_unlock() + local_irq_enable() spin_lock_irqsave() = spin_lock() + local_irq_save() spin_unlock_irqrestore() = spin_unlock() + local_irq_restore() |
spin_lock_bh() = spin_lock() + local_bh_disable() spin_unlock_bh() = spin_unlock() + local_bh_enable() |
int xxx_count = 0;/*定义文件打开次数计数*/ 2 3 static int xxx_open(struct inode *inode, struct file *filp) 4 { 5 ... 6 spinlock(&xxx_lock); 7 if (xxx count) { /*已经打开*/ 8 spin 9 return - EBUSY; 10 } 11 xxx_count++;/*增加使用计数*/ 12 spin_unlock(&xxx_lock); 13 ... 14 return 0; /* 成功 */ 15 } 16 17 static int xxx_release(struct inode *inode, struct file *filp) 18 { 19 ... 20 spinlock(&xxx_lock); 21 xxx_count--; /*减少使用计数*/ 22 spin_unlock(&xxx_lock); 23 24 return 0; 25 } |