【Linux应用与驱动开发】Linux内核的排队自旋锁
排队自旋锁(FIFO Ticket Spinlock)是 Linux 内核 2.6.25 版本中引入的一种新型自旋锁,它解决了传统自旋锁由于无序竞争导致的“公平性”问题。本文详细介绍了排队自旋锁的设计原理和具体实现,并与 操作系统采用的类似技术进行比较。最后讨论可能的扩展排队自旋锁的一些想法。
引言
自旋锁(Spinlock)是一种 Linux 内核中广泛运用的底层同步机制。自旋锁是一种工作于多处理器环境的特殊的锁,在单处理环境中自旋锁的操作被替换为空操作。当某个处理器上的内核执行线程申请自旋锁时,如果锁可用,则获得锁,然后执行临界区操作,最后释放锁;如果锁已被占用,线程并不会转入睡眠状态,而是忙等待该锁,一旦锁被释放,则第一个感知此信息的线程将获得锁。
长期以来,人们总是关注于自旋锁的和高效,而忽视了自旋锁的“公平”性。传统的自旋锁本质上用一个整数来表示,值为1代表锁未被占用。这种无序竞争的本质特点导致执行线程无法保证何时能取到锁,某些线程可能需要等待很长时间。随着计算机处理器个数的不断增长,这种“不公平”问题将会日益严重。
排队自旋锁(FIFO Ticket Spinlock)是 Linux 内核 2.6.25 版本引入的一种新型自旋锁,它通过保存执行线程申请锁的顺序信息解决了传统自旋锁的“不公平”问题。排队自旋锁的代码由 Linux 内核开发者 Nick Piggin 实现,目前只针对 x86 体系结构(包括 IA32 和 x86_64),相信很快就会被移植到其它平台。
传统自旋锁的实现与不足
Linux 内核自旋锁的底层数据结构 raw_spinlock_t 定义如下:
typedef struct {
unsigned int slock;
} raw_spinlock_t;
slock虽然被定义为无符号整数,但是实际上被当作有符号整数使用。slock值为1代表锁未被占用,值为0或负数代表锁被占用。初始化时slock被置为1。
线程通过宏 spin_lock 申请自旋锁。如果不考虑内核抢占,则 spin_lock 调用 __raw_spin_lock 函数,代码如下所示:
static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
asm volatile("\n1:\t"
LOCK_PREFIX " ; decb %0\n\t"
"jns 3f\n"
"2:\t"
"rep;nop\n\t"
"cmpb $0,%0\n\t"
"jle 2b\n\t"
"jmp 1b\n"
"3:\n\t"
: "+m" (lock->
相关文档:
一:前言
最近在研究android的sensor driver,主要是E-compass,其中用到了Linux input子系统.在网上也看了很多这方面的资料,感觉还是这篇分析的比较细致透彻,因此转载一下以便自己学习,同时和大家分享!
(这篇博客主要是以键盘驱动为例的,不过讲解的是Linux Input Subsystem,可以仔细的研究一下!)
键盘驱动将检 ......
已经某个端口号被占用,如何根据端口号得到占用它的进程的ID呢
用lsof
,lsof在ubuntu下的安装命令为apt-get install lsof
若已知端口号为15000,则对应查找命令为lsof -i | grep 15000
本机显示结果为:
host 3386
trinea 4u IPv4 16907 & ......
本文详细介绍了音频CD的基本知识,以及如何在Linux下编写实用的CD播放软件,内容涵盖音轨处理、播放控制和音量调节等诸多方面。
在目前的多媒体应用中,CD所承担的重要作用早已勿庸置疑,本文详细介绍了音频CD的基本知识,以及如何在Linux下编写实用的CD播放软件,内容涵盖音轨处理、播放控制和音量调节等诸多方面。
音频 ......