Aprendizaje impulsado por LINUX integrado 8 condiciones de carrera y problemas relacionados con la concurrencia (6) operación atómica entera

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;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_47273317/article/details/108085745
Recomendado
Clasificación