博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux内核-------同步机制(一)
阅读量:4180 次
发布时间:2019-05-26

本文共 3066 字,大约阅读时间需要 10 分钟。

一,介绍

在现代操作系统里,同一时间可能有多个内核执行流在执行,因此内核其实像多进程多线程编程一样也需要一些同步机制来同步各执行单元对共享数据的访问。尤其是在多处理器系统上,更需要一些同步机制来同步不同处理器上的执行单元对共享的数据的访问。在主流的Linux内核中包含了几乎所有现代的操作系统具有的同步机制,这些同步机制包括:原子操作、信号量(semaphore)、读写信号量(rw_semaphore)、自旋锁(spin_lock)、BKL(大内核锁)、读写锁(rwlock)、brlock(只包含在2.4内核中)、RCU(只包含在2.6内核中)和seqlock(只包含在2.6内核中)。

二,内核版本及体系结构

linux2.6.4 + i386

三,原子操作(linux-2.6.4\include\asm-i386\atomic.h)

原子操作

原子操作,就是该操作绝不会在执行完毕前被任何其他任务或事件打断,也就说,它的最小的执行单位,不可能有比它更小的执行单位,因此这里的原子实际是使用了物理学里的物质微粒的概念。

原子操作需要硬件的支持,因此是架构相关的,它们都使用汇编语言实现,因为C语言并不能实现这样的操作。

原子类型定义

typedef struct {         volatile int counter; } atomic_t;

通过上面的定义我们可以发现,该原子类型就是简单的封装了一个整形变量。其中volatile修饰字段告诉gcc不要对该类型的数据做优化处理,对它的访问都是对内存的访问,而不是对寄存器的访问。

原子操作API

atomic_read

#define atomic_read(v)		((v)->counter)

该函数对原子类型的变量进行原子读操作,因为是从内存中直接读取counter的值,因此可以保证原子性。它返回原子类型的变量v的值。

atomic_set

#define atomic_set(v,i)		(((v)->counter) = (i))

该函数设置v->counter的值为i,同样可以保证原子性。

atomic_add

static __inline__ void atomic_add(int i, atomic_t *v){	__asm__ __volatile__(		LOCK "addl %1,%0"		:"=m" (v->counter)		:"ir" (i), "m" (v->counter));}

上面的代码中含有内联汇编,内联汇编格式:

__asm__(assembler template                 /*汇编指令*/         :output operands                  /*输出数 */           :input operands                   /*输入数 */           :list of clobbered registers      /*被污染的寄存器 */           );

LOCK定义

#ifdef CONFIG_SMP#define LOCK "lock ; "#else#define LOCK ""#endif

如果当前的处理器是对称多内核的处理器,LOCK被定义为"lock:",避免其他进程修改数据。否则,定义为空。

对于atomic_add函数,从寄存器中读取i和内存中读取counter,进行相加,然后存入内存中。

atomic_sub

static __inline__ void atomic_sub(int i, atomic_t *v){	__asm__ __volatile__(		LOCK "subl %1,%0"		:"=m" (v->counter)		:"ir" (i), "m" (v->counter));}

从寄存器中读取i和内存中读取counter,进行相减,然后存入内存中。

atomic_sub_and_test

static __inline__ int atomic_sub_and_test(int i, atomic_t *v){	unsigned char c;	__asm__ __volatile__(		LOCK "subl %2,%0; sete %1"		:"=m" (v->counter), "=qm" (c)		:"ir" (i), "m" (v->counter) : "memory");	return c;}

该函数从原子类型的变量v中减去i,并判断结果是否为0,如果为0,返回真,否则返回假。

atomic_inc

static __inline__ void atomic_inc(atomic_t *v){	__asm__ __volatile__(		LOCK "incl %0"		:"=m" (v->counter)		:"m" (v->counter));}

该函数对原子类型变量v原子地增加1。

atomic_dec

static __inline__ void atomic_dec(atomic_t *v){	__asm__ __volatile__(		LOCK "decl %0"		:"=m" (v->counter)		:"m" (v->counter));}

该函数对原子类型的变量v原子地减1。

atomic_dec_and_test

static __inline__ int atomic_dec_and_test(atomic_t *v){	unsigned char c;	__asm__ __volatile__(		LOCK "decl %0; sete %1"		:"=m" (v->counter), "=qm" (c)		:"m" (v->counter) : "memory");	return c != 0;}

该函数对原子类型的变量v原子地减1,并判断结果是否为0,如果为0,返回真,否则返回假。

atomic_inc_and_test

static __inline__ int atomic_inc_and_test(atomic_t *v){	unsigned char c;	__asm__ __volatile__(		LOCK "incl %0; sete %1"		:"=m" (v->counter), "=qm" (c)		:"m" (v->counter) : "memory");	return c != 0;}

该函数对原子类型的变量v原子地增加1,并判断结果是否为0,如果为0,返回真,否则返回假。

atomic_add_negative

static __inline__ int atomic_add_negative(int i, atomic_t *v){	unsigned char c;	__asm__ __volatile__(		LOCK "addl %2,%0; sets %1"		:"=m" (v->counter), "=qm" (c)		:"ir" (i), "m" (v->counter) : "memory");	return c;}

该函数对原子类型的变量v原子地增加I,并判断结果是否为负数,如果是,返回真,否则返回假。

转载地址:http://fnrai.baihongyu.com/

你可能感兴趣的文章
B站疯传,太敏感!限2h删 !!!
查看>>
华为鸿蒙OS 2.0系统流畅度实测:差距到底多大?
查看>>
比特币又爆了。。。
查看>>
再见了,学术硕士!
查看>>
送一部华为平板电脑!!!
查看>>
20款优秀的数据可视化工具
查看>>
微信支付零花钱刷屏了!5万额度,能花又能借
查看>>
再见,win10!下一代操作系统已官宣。
查看>>
百度,终于干净了。
查看>>
0元点外卖攻略(防删速看)
查看>>
被录取了!
查看>>
公司能不能监控到微信聊天?
查看>>
Pandas函数速查手册(高清版)PDF
查看>>
我终于有字节工牌了!!!哈哈哈哈哈哈哈哈哈哈
查看>>
上海有哪些牛逼的互联网公司?
查看>>
再见了,Teamviewer!
查看>>
Windows 11 上手体验!网友:果里果气的……
查看>>
上岸哈工大!
查看>>
Zigbee协议栈中文说明
查看>>
TinyXML2 学习
查看>>