前EMC高级软件工程师,现小米分布式存储码农,关注分布式存储,文件系统,Linux内核。微博: http://weibo.com/u/2203007022
分类: LINUX
2013-09-21 20:26:11
传统的自旋锁实际上就是一个整数,值为1时表示没有被占用,值为0或负数时表示锁已经被占用,此时spin_lock循环等待,直到spin_unlock将自旋锁的值置为1,在这个过程中没有保存线程申请自旋锁的顺序信息,后进入等待的线程有可能先获得自旋锁。
排队自旋锁(FIFO Ticket Spinlock)是 Linux 内核 2.6.25 版本引入的一种新型自旋锁,它通过保存执行线程申请锁的顺序信息解决了这种问题,让先申请自旋锁的线程先得到锁。
1. Ticket spinlock的实现原理
排队自旋锁还是使用一个整形slock,并将其分为两个部分:
Next和Owner的长度与CPU的个数相关, 当CPU的个数 < 256时,Next和Owner为8位。当CPU的个数 > 256时,Next和Owner为16位。
#if (NR_CPUS < 256)
#define TICKET_SHIFT 8
...
#else
#define TICKET_SHIFT 16
点击(此处)折叠或打开
a. xaddw %w0, %1: 将inc和lock->slock的低16位置交换,并将相加后的值存贷lock->slock中.
例:slock = 0x00 00 11 10,操作之后slock = 0x00 00 12 10, inc = 0x00 00 11 10.
b. cmpb %h0, %b0: 比较inc的低8位(Owner)和高8位(Next),相等则获得锁返回,不相等则继续执行;
c. 不断轮询lock->slock, 等待直到Next和Owner相等。
解锁
点击(此处)折叠或打开