Linux内核——原子操作

跟着简叔学的,可以B站搜索 简说linux

原子变量

对原子变量的访问是源自的,linux内核自带的源子变量结构体定义如下(/include/linux/types.h):

1678087835689

竟然就是一个整型么!

对于原子变量的初始化ATOMIC_INIT不同体系架构都不一样。

原子变量的应用

同样,继续修改helloDev.c。

  1. 定义原子变量并初始化为1,之前的信号量和opencount不要了,

    1
    2
    3
    4
    // struct semaphore sema;
    // int open_count=0;
    static atomic_t can_open = ATOMIC_INIT(1);

  2. open操作改为

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int hello_open(struct inode *p, struct file *f)
    {
    if(!atomic_dec_and_test(&can_open))
    {
    printk(KERN_EMERG"device is busy,helloopen fall!!\r\n");
    automic_inc(&can_open);
    return -EBUSY;
    }
    printk(KERN_EMERG"hello_open ok~~~\r\n");
    return 0;
    }

    atomic_dec_and_testautomic_inc 这两个里面的操作不同的体系架构有着不一样的实现。以arm架构为例:全是汇编。。。。。

    1678088566696

    用宏定义去实现,嵌入汇编指令的操作。之前写过mips的汇编。现在忘的有点多。

    反正就是汇编语言实现了对原子变量的加减操作。如果是单核的话可以使用开关中断来保证原子操作

  3. close操作

    1
    2
    3
    4
    5
    6
    int hello_close(struct inode *inode ,struct file *filp)
    {
    automic_inc(&can_open);
    printk(KERN_INFO"hello_close ok");
    return 0;
    }

本篇的收获仅仅是原子变量的使用吧,初始化,然后加减操作。。至于怎么实现,也就大概那么回事。。。。。