Aprendizaje impulsado por LINUX integrado 8 condiciones de carrera y problemas relacionados con la concurrencia (6) operación atómica entera
1. Archivos de encabezado, funciones y descripciones
/* 结构体 atomic_t头文件位置:include/linux/types.h*/
typedef struct {
int counter;
} atomic_t;
/*
整型原子操作函数 :
atomic_add_return()、atomic_sub_return()
atomic_add()、atomic_sub()
atomic_inc()、 atomic_dec()
源码位置:include/asm-generic/atomic.h
*/
//执行v-counter + i操作,并返回结果,详见源码分析,附A1.1
int atomic_add_return(int i, atomic_t *v);
//执行v-counter + i操作,无返回值;
void atomic_add(int i, atomic_t *v);
//执行v-counter + 1操作,无返回值;
void atomic_inc(atomic_t *v);
执行v-counter - i操作,并返回结果,
int atomic_sub_return(int i, atomic_t *v);
//执行v-counter - i操作,无返回值
void atomic_sub(int i, atomic_t *v);
//执行v-counter - 1操作,无返回值;
void atomic_dec(atomic_t *v);
//设置v -> counter ==i
#define atomic_set(v, i) (((v)->counter) = (i))
//设置v -> counter == 1
#define ATOMIC_INIT(i) { (i) }
//读取v ->counter的值
#define atomic_read(v) (*(volatile int *)&(v)->counter)
/*
更多相关函数及组合函数可以参考如下文件:
include/asm-generic/atomic.h
include/asm-generic/atomic64.h
include/asm-generic/atomic-long.h
include/linux/atomic.h
arch/arm/include/asm/atomic.h
*/
2. Ejemplo de código (espacio del kernel)
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/atomic.h>
atomic_t atv ={
(0)};
static int f_open(struct inode * inode , struct file * file){
if(atomic_sub_return(1,&atv)){
//atomic_sub_return(1,&atv)操作具有原子性,不可被中断
printk("字符设备文件已经被打开!\n");
atomic_inc(&atv);
return -EBUSY;
}
printk("文件打开成功!\n");
return 0;
}
static int f_close(struct inode * inode , struct file * file){
atomic_inc(&atv);
printk("关闭字符设备文件完成");
return 0;
}
struct file_operations f_ops = {
.owner = THIS_MODULE,
.open = f_open,
.release = f_close
};
struct miscdevice misc_ops = {
.minor = MISC_DYNAMIC_MINOR,
.name = "atomic_test",
.fops = &f_ops
};
static int file_atomic_init(void){
misc_register(&misc_ops);
return 0;
}
static void file_atomic_exit(void){
misc_deregister(&misc_ops);
}
module_init(file_atomic_init);
module_exit(file_atomic_exit);
MODULE_LICENSE("GPL");
Tres, ejemplo de código (espacio de usuario)
Consulte el código de espacio de usuario de "8 Problemas relacionados con la carrera y la simultaneidad (4) Semáforo del aprendizaje impulsado por LINUX integrado"
Adjunto A1.1
/*
atomic_add_return()
源码位置:include/asm-generic/atomic.h
*/
static inline int atomic_add_return(int i, atomic_t *v)
{
unsigned long flags;
int temp;
raw_local_irq_save(flags);
temp = v->counter;
temp += i;
v->counter = temp;
raw_local_irq_restore(flags);
return temp;
}