内核的同步机制(原子锁)
来源:互联网 发布:以色列粮食进口数据 编辑:程序博客网 时间:2024/06/11 21:08
原子锁:
摘自《linux设备驱动开发详解》第七章
1.设置原子变量的值
void atomic_set(atomic_t *v, int i); //设置原子变量的值为i
atomic_t v = ATOMIC_INIT(0); //定义原子变量v并初始化为0
2.获取原子变量的值
atomic_read(atomic_t *v); //返回原子变量的值
3.原子变量加/减
void atomic_add(int i, atomic_t *v); //原子变量增加i
void atomic_sub(int i, atomic_t *v); //原子变量减少i
4.原子变量自增/自减
void atomic_inc(atomic_t *v); //原子变量增加1
void atomic_dec(atomic_t *v); //原子变量减少1
5.操作并测试
int atomic_inc_and_test(atomic_t *v);
int atomic_dec_and_test(atomic_t *v);
int atomic_sub_and_test(int i, atomic_t *v);
上述操作对原子变量执行自增、自减和减操作后(注意没有加)测试其是否为0,
为0 则返回true,否则返回false。
6.操作并返回
int atomic_add_return(int i, atomic_t *v);
int atomic_sub_return(int i, atomic_t *v);
int atomic_inc_return(atomic_t *v);
int atomic_dec_return(atomic_t *v);
上述操作对原子变量进行加/减和自增/自减操作,并返回新的值。
atomic。在atomic.h中有着它的定义以及操作函数。
typedef struct { volatile int counter; } atomic_t;#define ATOMIC_INIT(i) { (i) }/* * atomic_read - read atomic variable * @v: pointer of type atomic_t * * Atomically reads the value of @v. */#define atomic_read(v)((v)->counter)/* * atomic_set - set atomic variable * @v: pointer of type atomic_t * @i: required value * * Atomically sets the value of @v to @i. */#define atomic_set(v,i)((v)->counter = (i))/* * atomic_add - add integer to atomic variable * @i: integer value to add * @v: pointer of type atomic_t * * Atomically adds @i to @v. */static __inline__ void atomic_add(int i, atomic_t * v){if (cpu_has_llsc && R10000_LLSC_WAR) {unsigned long temp;__asm__ __volatile__(".setmips3\n""1:ll%0, %1# atomic_add\n""addu%0, %2\n""sc%0, %1\n""beqzl%0, 1b\n"".setmips0\n": "=&r" (temp), "=m" (v->counter): "Ir" (i), "m" (v->counter));} else if (cpu_has_llsc) {unsigned long temp;__asm__ __volatile__(".setmips3\n""1:ll%0, %1# atomic_add\n""addu%0, %2\n""sc%0, %1\n""beqz%0, 2f\n"".subsection 2\n""2:b1b\n"".previous\n"".setmips0\n": "=&r" (temp), "=m" (v->counter): "Ir" (i), "m" (v->counter));} else {unsigned long flags;raw_local_irq_save(flags);v->counter += i;raw_local_irq_restore(flags);}}/* * atomic_sub - subtract the atomic variable * @i: integer value to subtract * @v: pointer of type atomic_t * * Atomically subtracts @i from @v. */static __inline__ void atomic_sub(int i, atomic_t * v){if (cpu_has_llsc && R10000_LLSC_WAR) {unsigned long temp;__asm__ __volatile__(".setmips3\n""1:ll%0, %1# atomic_sub\n""subu%0, %2\n""sc%0, %1\n""beqzl%0, 1b\n"".setmips0\n": "=&r" (temp), "=m" (v->counter): "Ir" (i), "m" (v->counter));} else if (cpu_has_llsc) {unsigned long temp;__asm__ __volatile__(".setmips3\n""1:ll%0, %1# atomic_sub\n""subu%0, %2\n""sc%0, %1\n""beqz%0, 2f\n"".subsection 2\n""2:b1b\n"".previous\n"".setmips0\n": "=&r" (temp), "=m" (v->counter): "Ir" (i), "m" (v->counter));} else {unsigned long flags;raw_local_irq_save(flags);v->counter -= i;raw_local_irq_restore(flags);}}
/* * atomic_sub_and_test - subtract value from variable and test result * @i: integer value to subtract * @v: pointer of type atomic_t * * Atomically subtracts @i from @v and returns * true if the result is zero, or false for all * other cases. */#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)/* * atomic_inc_and_test - increment and test * @v: pointer of type atomic_t * * Atomically increments @v by 1 * and returns true if the result is zero, or false for all * other cases. */#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)/* * atomic_dec_and_test - decrement by 1 and test * @v: pointer of type atomic_t * * Atomically decrements @v by 1 and * returns true if the result is 0, or false for all other * cases. */#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)其实就是设置一个整形变量,对这个整形变量进行加减操作。可应用于对引用资源的计数。
在对这个整形变量进行加减的过程中,是在原子状态下进行的,汇编语言先不管,那几段少的可怜的c代码中,v->count进行加减的时候都是要关中断的。确保当前process占用内核。
原子锁也可以用于同步。比如下面的程序,至允许在一个进程中打开资源。程序也是摘自《linux设备驱动详解》
static atomic_t xxx_available = ATOMIC_INIT(1); /*定义原子变量*/static int xxx_open(struct inode *inode, struct file *filp){...if (!atomic_dec_and_test(&xxx_available))//如果xxx_available=0,返回1{atomic_inc(&xxx_available);return - EBUSY; /*已经打开*/ }...return 0; /* 成功*/}static int xxx_release(struct inode *inode, struct file *filp){atomic_inc(&xxx_available); /* 释放设备*/return 0;}
还有位操作的的原子锁,原理跟上面的差不多,只不过这是用bit操作,这样操作更简洁明了,非0即1,就是缺少了计数这个功能。
1.设置位
void set_bit(nr, void *addr);
上述操作设置addr 地址的第nr 位,所谓设置位即将位写为1。
2.清除位
void clear_bit(nr, void *addr);
上述操作清除addr 地址的第nr 位,所谓清除位即将位写为0。
3.改变位
void change_bit(nr, void *addr);
上述操作对addr 地址的第nr 位进行反置。
4.测试位
test_bit(nr, void *addr);
上述操作返回addr 地址的第nr 位。
5.测试并操作位
int test_and_set_bit(nr, void *addr);
int test_and_clear_bit(nr, void *addr);
int test_and_change_bit(nr, void *addr);
上述test_and_xxx_bit(nr, void *addr)操作等同于执行test_bit (nr, void *addr)后
再执行xxx_bit(nr, void *addr)。
- 内核的同步机制(原子锁)
- Linux内核的同步机制(一):原子操作
- Linux内核的同步机制:原子操作
- Linux内核的同步机制:原子操作
- Linux内核的同步机制:原子操作
- Linux内核同步机制之(一):原子操作
- Linux内核同步机制之(一):原子操作
- 内核同步机制——原子操作
- [linux] 内核同步机制 -- 原子操作
- Linux内核同步机制——原子操作
- 内核部件之同步机制之原子操作
- 内核同步机制之原子操作&优化和内存屏障
- Linux的原子操作与同步机制
- Linux的原子操作与同步机制
- Linux的原子操作与同步机制
- Linux的原子操作与同步机制
- Linux的原子操作与同步机制
- Linux的原子操作与同步机制
- 计算机视觉领域的一些牛人博客,超有实力的研究机构等的网站链接
- 纯命令行静默安装Oracle11gRAC+ASM+AIX
- “A valid provisioning profile for this executable was not found.”
- mysql_init()线程安全问题
- 前端工程师的价值体现在哪里?
- 内核的同步机制(原子锁)
- 第23贴:电阻 & 电容
- QT中 窗口部件的 背景图片 的设置
- activeMQ,spring的jmstemplate简单例子
- javadoc
- 关于团队激励的理念和实践
- .net面试题目
- CentOS常用用户管理命令
- POJ 1151 扫描线+线段树+离散化