【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->
相关文档:
1. HCI层协议概述:
HCI提供一套统一的方法来访问Bluetooth底层。如图所示:
从图上可以看出,Host Controller Interface(HCI) 就是用来沟通Host和Module。Host通常就是PC, Module则是以各种物理连接形式(USB,serial,pc-card等)连接到PC上的bluetooth Dongle。
在Host这一端:application,SDP,L2cap等协议 ......
例一:发送Signaling Packet:
Signaling Command是2个Bluetooth实体之间的L2CAP层命令传输。所以得Signaling Command使用CID 0x0001.
多个Command可以在一个C-frame(control frame)中发送。
如果要直接发送Signaling Command.需要建立SOCK_RAW类型的L2CAP连接Socket。这样才有机会自己填充Command Code,Identi ......
测量网卡的网络流量,linux下有两款小工具nload和iftop
下载源文件后configue && make && make install
个人比较喜欢iftop,它能动态的用简单的ASC图标识网卡当前流量
首行是网络流量刻度,
中间是与其它机器的流量,有个白底的bar直观的标识流量变化,后三列数据分别表示:
1. preceding 2 seco ......
1.
查找Java
项目中,main
方法定义在哪个文件
里.
切换到你要查找项目的目录下执行
grep -rlI '\
如果你觉得自己打字快,不怕麻烦执行如下命令也可以找到该文件
find -type f -name *.java -exec grep -l '\
2
快速的建立一个文件,并输入一些内容
cat >> filename
,输入一 ......