atomic类型api操作汇总(以原子方式操作某个变量)
#include<asm/atomic.h>
atomic_t 类型的变量。(一般操作的值不超过24位)
//设置值
void atomic_set(atomic_t *v, int i);
atomic_t v = ATOMIC_INIT(0);
//返回变量的值
int atomic_read(atomic_t *v)
//在值的基础上加i,
int atomic_add(int i, atomic_t *v)
//在值的基础上减i,
int atomic_sub(int i, atomic_t *v)
//类似++与--
void atomic_inc(atomic_t *v)
void atomic_dec(atomic_t *v)
类似的还有…
需要注意使用事项。
假设又两个线程在操作amount变量,其中A线程运行atomic_sub结束以后,还没运行到atomic_add之前,B线程也对这个amount变量操作,如果这个时候A线程刚好运行到了atomic_add函数,那么可能会造成两个线程同时访问amount加或者减一个不是1的操作,那么这个时候可能就会造成错误。。。
以原子方式操作某个bit
//设置/清除某个bit的值
void set_bit(nr, void *addr);
void clear_bit(nr, void *addr);
void change_bit(nr, void *addr);
//返回当前位的值
test_bit(nr, void *addr);
//设置并返回改位的值
int test_and_set_bit(nr, void *addr);
int test_and_clear_bit(nr, void *addr);
int test_and_change_bit(nr, void *addr);
例程演示:
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/fs.h>
#include<linux/slab.h>
#include<linux/timer.h>
#include<linux/sched.h>
#include<linux/list.h>
#include<linux/interrupt.h>
#include<linux/jiffies.h>
#include<linux/wait.h>
#include<linux/cdev.h> //cdev_init() cdev_add() cdev_del()
#include<linux/types.h> //dev_t
#include<linux/kdev_t.h> //有两个宏获取主设备号和次设备号
#include<linux/uaccess.h> //container_of
MODULE_AUTHOR("Tan xujia");
MODULE_LICENSE("Dual BSD/GPL");
volatile long unsigned int *q;
static
int __init hello_init (void)
{
int ret = 0, index = 0;
printk("hello_init\n");
q = kmalloc(sizeof(int), GFP_KERNEL);
memset(q, 0, sizeof(int));
int o = test_and_set_bit(2, q); //返回的是上一次的值
printk("o = %d\n", o);
o = test_and_clear_bit(2, q);//返回的是上一次的值
printk("o = %d\n", o);
o = test_and_change_bit(2, q);//返回的是上一次的值
printk("o = %d\n", o);
return ret;
}
static
void __exit hello_exit (void)
{
int index = 0;
printk("hello_exit\n");
kfree(q);
}
module_init(hello_init);
module_exit(hello_exit);