内核同步之原子操作

原子操作

所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何上下文切换。

内核提供了两类原子操作接口:整数原子操作,位原子操作。

原子整数操作

原子整数分为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返回真,否则返回假

 

原子位操作

内核提供了针对位这一级数据进行操作的函数,他们定义在中。位操作函数是对普通的内存地址进行操作的,它的参数是一个指针和一个位号。标准原子位操作见下表:

表格 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位

你可能感兴趣的:(Linux内核)