首页 > 其他分享 >原子操作的实现原理与使用-03

原子操作的实现原理与使用-03

时间:2024-05-03 15:22:26浏览次数:24  
标签:03 r1 原子 atomic ARMv6 操作 原理 内核

所谓“原子操作”就是这个操作不会被打断。Linux有2种原子操作:原子变量、原子位。

 

原子变量的内核操作函数

原子变量的操作函数在Linux内核文件arch\arm\include\asm\atomic.h中。

原子变量类型如下,实际上就是一个结构体(内核文件include/linux/types.h):

 

 

原子变量的内核实现

注意:SMP就是Symmetric Multi-Processors,对称多处理器;UP即Uni-Processor,系统只有一个单核CPU。

这些函数都是在Linux内核文件arch\arm\include\asm\atomic.h中。

atomic_read,atomic_set这些操作都只需要一条汇编指令,所以它们本身就是不可打断的。

问题在于atomic_inc这类操作,要读出、修改、写回。

以atomic_inc为例,在atomic.h文件中,如下定义:

 

从上面的宏可以知道,一个ATOMIC_OPS定义了3个函数。比如“ATOMIC_OPS(add, +=, add)”就定义了这3个函数:

 

我们以ATOMIC_OP(add, +=, add)为例,看它是如何实现atomic_add函数的,对于UP系统、SMP系统,分别有不同的实现方法。

ATOMIC_OP在UP系统中的实现

对于ARMv6以下的CPU系统,不支持SMP。原子变量的操作简单粗暴:关中断,中断都关了,谁能来打断我?代码如下(arch\arm\include\asm\atomic.h):

 

ATOMIC_OPSMP系统中的实现

对于ARMv6及以上的CPU,有一些特殊的汇编指令来实现原子操作,不再需要关中断,代码如下(arch\arm\include\asm\atomic.h):

 

在ARMv6及以上的架构中,有ldrex、strex指令,ex表示exclude,意为独占地。这2条指令要配合使用,举例如下:

① 读出:ldrex  r0, [r1]

读取r1所指内存的数据,存入r0;并且标记r1所指内存为“独占访问”。

如果有其他程序再次执行“ldrex  r0, [r1]”,一样会成功,一样会标记r1所指内存为“独占访问”。

② 修改r0的值

③ 写入:strex  r2, r0, [r1]:

如果r1的“独占访问”标记还存在,则把r0的新值写入r1所指内存,并且清除“独占访问”的标记,把r2设为0表示成功。

如果r1的“独占访问”标记不存在了,就不会更新内存,并且把r2设为1表示失败。

 

假设这样的抢占场景:

① 程序A在读出、修改某个变量时,被程序B抢占了;

② 程序B先完成了操作,程序B的strex操作会清除“独占访问”的标记;

③ 轮到程序A执行剩下的写入操作时,它发现独占访问”标记不存在了,于是取消写入操作。

这就避免了这样的事情发生:程序A、B同时修改这个变量,并且都自认为成功了。

 

举报个例子,比如atomic_dec,假设一开始变量值为1,程序A本想把值从1变为0;但是中途被程序B先把值从1变成0了;但是没关系,程序A里会再次读出新值、修改、写入,最终这个值被程序A从0改为-1。

在ARMv6及以上的架构中,原子操作不再需要关闭中断,关中断的花销太大了。并且关中断并不适合SMP多CPU系统,你关了CPU0的中断,CPU1也可能会来执行些操作啊。

在ARMv6及以上的架构中,原子操作的执行过程是可以被打断的,但是它的效果符合“原子”的定义:一个完整的“读、修改、写入”原子的,不会被别的程序打断。它的思路很简单:如果被别的程序打断了,那就重来,最后总会成功的。

原子变量使用案例

现在可以使用原子变量实现:只能有一个APP访问驱动程序。代码如下:

 

第5行的atomic_dec_and_test,这是一个原子操作,在ARMv6以下的CPU架构中,这个函数是在关中断的情况下执行的,它确实是“原子的”,执行过程不被打断。

但是在ARMv6及以上的CPU架构中,这个函数其实是可以被打断的,但是它实现了原子操作的效果,如下图所示:

 

原子位介绍

原子位的内核操作函数

能操作原子变量,再去操作其中的某一位,不是挺简单的嘛?不过不需要我们自己去实现,内核做好了。

原子位的操作函数在Linux内核文件arch\arm\include\asm\bitops.h中,下表中p是一个unsigned long指针。

 

原子位的内核实现

在ARMv6以下的架构里,不支持SMP系统,原子位的操作函数也是简单粗暴:关中断。以set_bit函数为例,代码在内核文件arch\arm\include\asm\bitops.h中,如下

 

在ARMv6及以上的架构中,不需要关中断,有ldrex、strex等指令,这些指令的作用在前面介绍过。还是以set_bit函数为例,代码如下:

 

标签:03,r1,原子,atomic,ARMv6,操作,原理,内核
From: https://www.cnblogs.com/liusiluandzhangkun/p/18171240

相关文章

  • 【Netty】【XXL-JOB】时间轮的原理以及应用分析
    1 前言今天晚上看了一本70多页的讲解时间轮的PDF,从是什么为什么以及原理到源码中的应用分析,讲的真好。这节我就按我理解的思路捋一下,记录一下哈。2 时间轮概述2.1 时间轮是什么时间轮是一种高效利用线程资源进行批量化调度的一种调度模型。把大批量的调度任务全部绑......
  • python3.12.3下使用flask-script的Command报错AttributeError: module 'inspect' has
    错误如下图:问题原因:因为inspect.getargspec在3.11+中已弃用。翻看源码如下图解决方案:解决方法是使用inspect.fullargspec代替,并添加3个虚拟变量,因为getfullargspec将返回7个项目而不是4个:args,varargs,keywords,defaults,foo,foo1,foo2=inspect.getf......
  • 初中中考英语词汇大全003掌握常用词汇,轻松应对考试
    PDF格式公众号回复关键字:ZKCH0031ancient古代的;古老的modern现代的;时髦的official官方的;正式的;公务员foreign外国的;外来的2soonerorlater迟早;早晚有一天allthetime一直;始终overandover一遍又一遍;反复地inahurry匆忙地;立即;很快地3slower更慢......
  • 蚂蚁面试:Springcloud核心组件的底层原理,你知道多少?
    文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录博客园版为您奉上珍贵的学习资源:免费赠送:《尼恩Java面试宝典》持续更新+史上最全+面试必备2000页+面试必备+大厂必备+涨薪必备免费赠送:《尼恩技术圣经+高并发系列PDF》,帮你实现技术自由,完成职业升级,薪......
  • 力扣-303. 区域和检索
    1.题目题目地址(303.区域和检索-数组不可变-力扣(LeetCode))https://leetcode.cn/problems/range-sum-query-immutable/题目描述给定一个整数数组 nums,处理以下类型的多个查询:计算索引 left 和 right (包含left和right)之间的nums元素的和,其中 left<=righ......
  • 对于计算机微机结构及其工作原理的认识
    通过硬件组成角度谈谈我对于计算机微机的认识,计算机微机首先说其结构,其结构包括时钟、CPU、储存器以及IO接口。其中,时钟类似于一个开关和乐队的“指挥”,它控制着计算机程序运行的顺序,并且保持计算机多个程序并发执行的时间分配。而CPU则是最重要的组成部分了,它主要包括运算器、控......
  • redis集群原理
    由于redis主从,哨兵都有一些不便之处,redis就提出了集群的概念,并真正实现了。 在redis3.0以前的版本要实现集群一般是借助哨兵sentinel工具来监控master节点的状态,如果master节点异常,则会做主从切换,将某一台slave作为master,哨兵的配置略微复杂,并且性能和高可用性等各方面表现一般......
  • Redis核心数据结构与高性能原理
    参考-图灵课堂-https://vip.tulingxueyuan.cnhttps://www.runoob.com/redis/redis-tutorial.html 常见得数据类型:Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sortedset:有序集合)。stringstring是redis最基本的类型,你可以理解成与Memcached一......
  • [USACO24OPEN] The 'Winning' Gene S
    [USACO24OPEN]The'Winning'GeneS题目背景注意:本题的内存限制为512MB,通常限制的2倍。题目描述在多年举办比赛并看着Bessie一次又一次地获得第一名后,FarmerJohn意识到这绝非偶然。他得出结论,Bessie一定将胜利写进了DNA,于是他开始寻找这种「胜利」基因。他设计了一......
  • 简单解决version 'GLIBC_2.34' not found,version 'GLIBC_2.25' not found
    简单解决version'GLIBC_2.34'notfound,version'GLIBC_2.25'notfound无需手动下载安装包编译前言很多博客都是要手动下载安装包进行编译升级,但这样很容易导致系统崩溃,本博文提供一个简单的方法,参考自博客1,博客2.检查版本strings/usr/lib64/libc.so.6|grepGLIBC_或者......