原子操作
所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何上下文切换。
内核提供了两类原子操作接口:整数原子操作,位原子操作。
原子整数操作
原子整数分为32位原子整数和64位原子整数,类型分别为atomic_t和atomic64_t,使用自定义类型的原因:
1) 让原子函数只接受atomic_t类型的操作数可以确保原子操作只与这种特殊类型的数据一起使用。同时这也保证了该类型的数据不会被传递给其他任何非原子函数。
2) 使用atomic_t类型确保编译器不对相应的值进行访问优化——这点使得原子操作最终接收到正确的内存地址,而不只是一个别名。
3) 在不同体系结构上实现原子操作的时候,使用atomic_t可以屏蔽期间的差异。
表格 1 32位原子整数函数
原子整数操作 | 描述 |
ATOMIC_INIT(int i) | 在声明一个atomic_t变量时,将它初始化为i |
int atomic_read(atomic_t *v) | 原子地读取整数变量v |
void atomic_set(atomic_t *v, int i) | 原子地设置v值为i |
void atomic_add(int i, atomic_t *v) | 原子地给v加i |
void atomic_sub(int i, atomic_t *v) | 原子地从v减i |
void atomic_inc(atomic_t *v) | 原子地给v加1 |
void atomic_dec(atomic_t *v) | 原子地给v减1 |
int atomic_sub_and_test(int i, atomic_t *v) | 原子地从v减i,若结果等于0返回真,否则返回假 |
int atomic_add_negative(int i, atomic_t *v) | 原子地从v加i,若结果是负数返回真,否则返回假 |
int atomic_dec_and_test(atomic_t *v) | 原子地从v减1,若结果等于0返回真,否则返回假 |
int atomic_inc_and_test(atomic_t *v) | 原子地从v加1,若结果等于0返回真,否则返回假 |
原子位操作
内核提供了针对位这一级数据进行操作的函数,他们定义在<asm/bitop.h>中。位操作函数是对普通的内存地址进行操作的,它的参数是一个指针和一个位号。标准原子位操作见下表:
表格 3 原子位操作
原子位操作 | 描述 |
void set_bit(int nr, void *addr) | 原子地设置addr所指对象的第nr位 |
void clear_bit(int nr, void *addr) | 原子地清空addr所指对象的第nr位 |
void change_bit(int nr, void *addr) | 原子地翻转addr所指对象的第nr位 |
int test_and_set_bit(int nr, void *addr) | 原子地设置addr所指对象的第nr位,并返回原先的值 |
int test_and_clear_bit(int nr, void *addr) | 原子地清空addr所指对象的第nr位,并返回原先的值 |
int test_and_change_bit(int nr, void *addr) | 原子地翻转addr所指对象的第nr位,并返回原先的值 |
int test_bit(int nr, void *addr) | 原子地返回addr所指对象的第nr位 |