原子操作--ARM架构
说明:内核版本号为3.10.101
一、ARM架构中的原子操作实现
在原子操作(一)中我们已经提到,各个架构组织为“复仇者”联盟,统一了基本的原子变量操作,这里我们就拿atomic_dec(v)来看看通天ARM的实现。
首先是atomic_dec(v)原子减一操作的宏定义。这个宏的定义在文件arch/arm/include/asm/atomic.h中:
#define atomic_dec(v) atomic_sub(1, v)
对于ARM架构不同的版本,stomic_sub(i,v)的实现是不一样的。具体而言,在ARMv6之前的版本定义如下:
#define atomic_sub(i, v) (void) atomic_sub_return(i, v)
而ARMv6以后的版本则将atomic_sub()实现为static 内联函数,具体见第二节。
二、ARMv6以前的版本的实现
ARMv6之前的版本将atomic_sub()宏定义为atomic_sub_return()函数,其实现也在文件arch/arm/include/asm/atomic.h中。而这个atomic_sub_return()函数根据版本的不同也有两个不同的实现。我们这里只关注ARMv6之前版本的实现。
/* ARMv6 以前的版本:不支持SMP */
static inline int atomic_sub_return(int i, atomic_t *v) {
unsigned long flags;
int val;
raw_local_irq_save(flags); //关本地中断
val = v->counter;
v->counter = val -= i;
raw_local_irq_restore(flags); //开中断
return val;
}
可以看到,对v->counter的减一操作是一个临界区,指令的执行不能被打断,内存的访问也需要保持没有干扰。
ARMv6以前的版本通过关本地中断来保护这块临界区,看起来相当简单,其奥秘就在于ARMv6以前的版本不支持SMP。
在系统不支持SMP的情况下,我们关掉本地中断可以防止下面几种意外:
1) 关掉本地中断后,在对v->counter实施"减一"的过程中不会被外部中断打断;
2) 系统不支持SMP,可以保证在本地cpu访问v->counter和val变量内存的过程中不会有其他cpu访问这些内存。
问题:
1. 虽然在临界区内不会有其他cpu访问 v->counter和val,但是能够保证不会有DMA操作这些内存么?
2. 虽然禁止了中断,但是可以保证期间此cpu不会被抢占或者因为其他原因放弃调度么?
答:
1. DMA在操作内存前会通过DMA中断、总线仲裁来与cpu的内存访问进行协调。这里已经关掉本地中断,且是UP系统,所以不会干扰。
2. 在UP系统中没有内核抢占;从代码上来看,临界区这一段没有主动放弃cpu;另外,我们禁止了本地中断,也就是禁止了时钟中断,这样在开中断前就不会有机会进行调度检查,保证临界区在开中断前一直运行。
三. ARMv7以后的架构
从ARMv6T2以后的版本中,ARM和Thumb指令集开始采用了新一代"独占访问"指令"Load-Exclusive and Store-Exclusive "来实现原子操作。独占访问的秘诀就在于系统中通过exclusive monitor来实现独占访问的监控。内核中atomic_sub()的具体实现如下所示:
/*
* ARMv6 UP and SMP safe atomic ops. We use load exclusive and
* store exclusive to ensure that these are atomic. We may loop
* to ensure that the update happens.
*/
static inline void atomic_sub(int i, atomic_t *v)
{
unsigned long tmp;
int result;
__asm__ __volatile__("@ atomic_sub\n" /* 优化屏障,防止编译器优化 */
"1: ldrex %0, [%3]\n" /*【1】独占方式加载v->counter到result*/
" sub %0, %0, %4\n" /*【2】result减一*/
" strex %1, %0, [%3]\n" /*【3】独占方式将result值写回v->counter*/
" teq %1, #0\n" /*【4】判断strex更新内存是否成*/
" bne 1b" /*【5】不成功跳转到1:*/
: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) /*输出部*/
: "r" (&v->counter), "Ir" (i) /*输入部*/
: "cc"); /*损坏部*/
}
访存指令LDREX/STREX和普通的LDR/STR访存指令不一样,它是“独占”访存指令。这对指令访存过程由一个称作“exclusive monitor”的部件来监视是否可以进行独占访问。
先看看这对独占访存指令:
(1)LDREX R1 ,[R0] 指令是以独占的方式从R0所指的地址中取一个字存放到R0中;
(2)STREX R2,R1,[R0] 指令是以独占的方式用R1来更新内存,如果独占访问条件允许,则更新成功并返回0到R2,否则失败返回1到R2。
了解LDREX和STREX的基本原理后,理一理上面atomic_sub()原子更新(减一)atomic_t * v的实现流程:
(1) 从内存中读取v->counter值到一个寄存器中(result),并更新exclusive monitor状态为独占访问;
(2)result减一操作;
(3)尝试将result的值写入v->counter地址,如果exclusive monitor允许独占写存,则修改内存成功并将tmp设置为0 ,否则tmp设置1;
(4)查看tmp的值是否为0 ,如果不为0表示上面的更新v->counter失败,再次跳转会(1)执行。
一旦STREX指令执行成功,就表示这次内存访问没有受到其他干扰,保证了内存更新操作的原子性。
原子操作--ARM架构的更多相关文章
- X86架构与ARM架构比较(摘录自网络)
引言 CPU是怎样运作的? CPU的运作与人脑的运作差不多.先谈一下人这个系统的工作方式.眼镜.耳朵.舌头.皮肤等等感觉器官接收到"触觉",把信息传给大脑,大脑把信息处理后,把处理 ...
- X86 架构和 ARM 架构
1.关于x86架构 X86是一个intel通用计算机系列的标准编号缩写,也标识一套通用的计算机指令集合,X86是由Intel推出的一种复杂指令集,用于控制芯片的运行的程序,现在X86已经广泛运用到了家 ...
- 百度全新的ARM架构服务器,一个2U机箱装6台,每台4个3T硬盘,每个机箱共72TB
1月11日,中国科学院原秘书长.国家科技重大专项国务院咨询评估组专家侯自强,来到百度南京数据中心,和他一起的还有中国工程院院士倪光南以及工业和信息化部电信研究院传输研究所副所长石友康等人.他们看到的是 ...
- 让x86的android模拟器能模拟arm架构系统
网上介绍共计三种模拟器比较常用,分别是bluestacks.andy和Genymotion,前者支持ARM架构,中者支持远程控制,后者启动速度快,各有优缺点. 如果要用genymotion模拟arm的 ...
- X86架构与ARM架构比较
引言 CPU是怎样运作的? CPU的运作与人脑的运作差不多.先谈一下人这个系统的工作方式.眼镜.耳朵.舌头.皮肤等等感觉器官接收到“触觉”,把信息传给大脑,大脑把信息处理后,把处理结果送给手.脚.嘴等 ...
- ARM架构和X86架构对比
转载地址 我们就ARM架构的系统与X86架构系统的特性进行一个系统分析,方便用户在选择系统时进行理性.合理的比价分析. 一.性能: X86结构的电脑无论如何都比ARM结构的系统在性能方面要快得多.强得 ...
- ARM架构解析
ARM架构解析 (2014-11-23 21:56:53) 转载▼ 标签: francis_hao arm架构 arm核 soc 分类: MCU 先来谈一下ARM的发展史:1978年12月5日,物理学 ...
- ARM架构
ARM架构(过去称作进阶精简指令集机器(Advanced RISC Machine),更早称作Acorn RISC Machine)是一个32位元精简指令集(RISC) 中央处理器(processor ...
- 树莓派3b+_32位linux系统arm架构安装JDK
如图我的Raspbian系统如下图版本信息: 可以看到是armv7l,我查了一下是32位的arm架构,即下载第一个就好了 然后用SSH Secure Shell远程上去把压缩包或者解压后的文件传过去 ...
随机推荐
- [MAC]用beamoff给VMware的Mac OS X 10.10.x加速
MAC OS X 10.10.x Yosemite在VMWare中实在是太慢了,卡出翔!好在高人多,请装beamoff!详见:https://github.com/JasF/beamoff.git C ...
- android 开发 程序中下载安装APK文件 问题汇总 解析程序包时出现问题
1 若把APK文件保存到应用程序的files目录下,则一定注意保存时使用 FileOutputStream os = openFileOutput(fileName, MODE_WORLD_READA ...
- json与对象转化
/// <summary> /// 把JSON字符串还原为对象 /// </summary> /// <typeparam name="T">对 ...
- CU上看到的一个简单的算法帖子
今天也是明白了,编程与数学的关系.例子很简单,不过能说明问题. 如果我们优化算法只从计算机特性来考虑,那么我们的人脑也成了计算机.不要忘记数学对于算法的重要影响. 题目: 返回小于数字 N 的所有 3 ...
- WPF简单导航框架(Window与Page互相调用)
相当多的WPF程序都有着丰富的页面和功能,如何使程序在不同页面间转换并降低资源占用,选择适合自己的导航框架就很重要了.最近花了一点时间做了一个简单的导航框架,并在这个过程中对Window.Page.U ...
- java环境基础步骤 maven
1. 下载maven,解压到合适的位置 a. 下载 Maven ,其实就是一个压缩包,解压一下 b. 配置一下环境变量 有两个环境变量可以配置: MAVEN_HOME = D:\maven ...
- c++ 对象的内存布局
之前介绍过了普通对象比如系统自带的int等对象的对齐方式,在学习类型转换的时候遇到了自定义类型的继承体系中的downcast与upcast. 于是顺藤摸瓜,摸到了这里.发现还是 陈皓的博客里面写的最早 ...
- Java基础知识系列——日期
日期类型也是在编程中经常用到的一种数据类型. Java中的日期类型为Date. 另外需要记住三个类: java.text.SimpleDateFormat; java.util.Calendar; j ...
- 转载:shell脚本之sed使用----替换、变量、转义字符
sed替换的基本语法为:----s后面跟的是分隔符,原字符串可使用.*这种正则表达式进行整行替换 代码如下: sed 's/原字符串/替换字符串/' 单引号里面,s表示替换,三根斜线中间是替换的样式, ...
- (转载)持续集成(第二版)[来自:Martin Fowler]
转载自:iTech的博客 持续集成(第二版) 作者:Martin Fowler 译者:雷镇 持续集成 是一种软件开发实践.在持续集成中,团队成员频繁集成他们的工作成果,一般每人每天至少集成一次,也可以 ...