[转]ARM平台下独占访问指令LDREX和STREX

时间:2021-11-08 22:19:32

参考:ARM平台下独占访问指令LDREX和STREX的原理与使用详解

全文转载如下:

为了实现线程间同步,一般都要在执行关键代码段之前加互斥(Mutex)锁,且在执行完关键代码段之后解锁。为了实现所谓的互斥锁的概念,一般都需要所在平台提供支持。

本文主要用来说明ARM平台上特有的独占访问指令LDREX和STREX的工作原理,以及如何使用。而它们也是ARM平台上,实现互斥锁等线程同步工具的基础。

我们先来看看LDREX和STREX两条指令的语义。其实LDREX和STREX指令,是将单纯的更新内存的原子操作分成了两个独立的步骤。

1)LDREX用来读取内存中的值,并标记对该段内存的独占访问:

LDREX Rx, [Ry]  

上面的指令意味着,读取寄存器Ry指向的4字节内存值,将其保存到Rx寄存器中,同时标记对Ry指向内存区域的独占访问。

如果执行LDREX指令的时候发现已经被标记为独占访问了,并不会对指令的执行产生影响。

2)而STREX在更新内存数值时,会检查该段内存是否已经被标记为独占访问,并以此来决定是否更新内存中的值:

STREX Rx, Ry, [Rz]  

如果执行这条指令的时候发现已经被标记为独占访问了,则将寄存器Ry中的值更新到寄存器Rz指向的内存,并将寄存器Rx设置成0。指令执行成功后,会将独占访问标记位清除。

而如果执行这条指令的时候发现没有设置独占标记,则不会更新内存,且将寄存器Rx的值设置成1。

一旦某条STREX指令执行成功后,以后再对同一段内存尝试使用STREX指令更新的时候,会发现独占标记已经被清空了,就不能再更新了,从而实现独占访问的机制。

大致的流程就是这样,但是ARM内部为了实现这个功能,还有不少复杂的情况要处理。

在ARM系统中,内存有两种不同且对立的属性,即共享(Shareable)和非共享(Non-shareable)。共享意味着该段内存可以被系统中不同处理器访问到,这些处理器可以是同构的也可以是异构的。而非共享,则相反,意味着该段内存只能被系统中的一个处理器所访问到,对别的处理器来说不可见。

为了实现独占访问,ARM系统中还特别提供了所谓独占监视器(Exclusive Monitor)的东西,其结构大致如下:

[转]ARM平台下独占访问指令LDREX和STREX

可以看出来,一共有两种类型的独占监视器。每一个处理器内部都有一个本地监视器(Local Monitor),且在整个系统范围内还有一个全局监视器(Global Monitor)。

如果要对非共享内存区中的值进行独占访问,只需要涉及本处理器内部的本地监视器就可以了;而如果要对共享内存区中的内存进行独占访问,除了要涉及到本处理器内部的本地监视器外,由于该内存区域可以被系统中所有处理器访问到,因此还必须要由全局监视器来协调。

对于本地监视器来说,它只标记了本处理器对某段内存的独占访问,在调用LDREX指令时设置独占访问标志,在调用STREX指令时清除独占访问标志。

而对于全局监视器来说,它可以标记每个处理器对某段内存的独占访问。也就是说,当一个处理器调用LDREX访问某段共享内存时,全局监视器只会设置针对该处理器的独占访问标记,不会影响到其它的处理器。当在以下两种情况下,会清除某个处理器的独占访问标记:

1)当该处理器调用LDREX指令,申请独占访问另一段内存时;

2)当别的处理器成功更新了该段独占访问内存值时。

对于第二种情况,也就是说,当独占内存访问内存的值在任何情况下,被任何一个处理器更改过之后,所有申请独占该段内存的处理器的独占标记都会被清空。

另外,更新内存的操作不一定非要是STREX指令,任何其它存储指令都可以。但如果不是STREX的话,则没法保证独占访问性。

现在的处理器基本上都是多核的,一个芯片上集成了多个处理器。而且对于一般的操作系统,系统内存基本上都被设置上了共享属性,也就是说对系统中所有处理器可见。因此,我们这里主要分析多核系统中对共享内存的独占访问的情况。

为了更加清楚的说明,我们可以举一个例子。假设系统中有两个处理器内核,而一个程序由三个线程组成,其中两个线程被分配到了第一个处理器上,另外一个线程被分配到了第二个处理器上。且他们的执行序列如下:

[转]ARM平台下独占访问指令LDREX和STREX

大致经历的步骤如下:

1)CPU2上的线程3最早执行LDREX,锁定某段共享内存区域。它会相应更新本地监视器和全局监视器。

2)然后,CPU1上的线程1执行LDREX,它也会更新本地监视器和全局监视器。这时在全局监视器上,CPU1和CPU2都对该段内存做了独占标记。

3)接着,CPU1上的线程2执行LDREX指令,它会发现本处理器的本地监视器对该段内存有了独占标记,同时全局监视器上CPU1也对该段内存做了独占标记,但这并不会影响这条指令的操作。

4)再下来,CPU1上的线程1最先执行了STREX指令,尝试更新该段内存的值。它会发现本地监视器对该段内存是有独占标记的,而全局监视器上CPU1也有该段内存的独占标记,则更新内存值成功。同时,清除本地监视器对该段内存的独占标记,还有全局监视器所有处理器对该段内存的独占标记。

5)下面,CPU2上的线程3执行STREX指令,也想更新该段内存值。它会发现本地监视器拥有对该段内存的独占标记,但是在全局监视器上CPU1没有了该段内存的独占标记(前面一步清空了),则更新不成功。

6)最后,CPU1上的线程2执行STREX指令,试着更新该段内存值。它会发现本地监视器已经没有了对该段内存的独占标记(第4步清除了),则直接更新失败,不需要再查全局监视器了。

所以,可以看出来,这套机制的精髓就是,无论有多少个处理器,有多少个地方会申请对同一个内存段进行操作,保证只有最早的更新可以成功,这之后的更新都会失败。失败了就证明对该段内存有访问冲突了。实际的使用中,可以重新用LDREX读取该段内存中保存的最新值,再处理一次,再尝试保存,直到成功为止。

还有一点需要说明,LDREX和STREX是对内存中的一个字(Word,32 bit)进行独占访问的指令。如果想独占访问的内存区域不是一个字,还有其它的指令:

1)LDREXB和STREXB:对内存中的一个字节(Byte,8 bit)进行独占访问;

2)LDREXH和STREXH:中的一个半字(Half Word,16 bit)进行独占访问;

3)LDREXD和STREXD:中的一个双字(Double Word,64 bit)进行独占访问。

它们必须配对使用,不能混用。

[转]ARM平台下独占访问指令LDREX和STREX的更多相关文章

  1. 4G通信模块在ARM平台下的应用

    4G模块是连接物与物的重要载体,是终端设备接入物联网的核心部件之一.随着4G的普及,许多新兴市场对4G通信模块的需求都在日益扩大,那么在ARM平台的嵌入式设备上如何快速的应用4G模块呢? 4G通信模块 ...

  2. 4G 通信模块在ARM 平台下的应用

    收藏 评论(0) 分享到 微博 QQ 微信 LinkedIn 4G模块是连接物与物的重要载体,是终端设备接入物联网的核心部件之一,随着4G的普及,许多新兴市场对4G通信模块的需求都在日益扩大,那么在A ...

  3. Linux Kernel之flush_cache_all在ARM平台下是如何实现的【转】

    转自:http://blog.csdn.net/u011461299/article/details/10199989 版权声明:本文为博主原创文章,未经博主允许不得转载. 在驱动程序的设计中,我们可 ...

  4. ARM伪指令和协处理器访问指令

    伪指令本身没有对应的机器码 .global声明全局符号,点事GUN汇编的特点 .data定义数据段 .equ DA #0x89 定义宏 .align 4 4字节对齐 mov 指令里的立即数只能是8位的 ...

  5. Mplayer ARM平台下交叉编译

    下载MPlayer http://www.mplayerhq.hu/design7/dload.html 编译环境 系统 : ubuntu 11.04 交叉编译器版本 : Sourcery G++ L ...

  6. NDK编程的一个坑—Arm平台下的类型转换

    最近在做DNN定点化相关的工作,DNN定点化就是把float表示的模型压缩成char表示,虽然会损失精度,但是由于DNN训练的模型值比较接近且范围较小,实际上带来的性能损失非常小.DNN定点化的好处是 ...

  7. ARM 平台下的 SSHD 配置

    sshd_config 文件中 允许 root 用户登录 PermitRootLogin yes 配置为内部的 sftp Subsystem sftp internal-sftp key 配置 ssh ...

  8. 【嵌入式开发】 ARM 汇编 (指令分类 | 伪指令 | 协处理器访问指令)

    作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42408137 转载请著名出处 本博客相关文档下载 :  -- AR ...

  9. (二十三)ARM平台NEON指令的编译和优化

    ARM平台NEON指令的编译和优化 本文介绍了ARM平台基于ARM v7-A架构的ARM Cortex-A系列处理器(Cortex-A5, Cortex-A7,Cortex-A8, Cortex-A9 ...

随机推荐

  1. 4、Python:strip(),split()

    1.strip()函数 strip()是删除'()'里面的字符,当()为空时,默认删除空白符(包括'\n','\r','\t','') (1)s.strip(rm)        删除s字符串中开头. ...

  2. 数字证书文件格式(cer和pfx)的区别

    作为文件形式存在的证书一般有这几种格式: 1.带有私钥的证书 由Public Key Cryptography Standards #12,PKCS#12标准定义,包含了公钥和私钥的二进制格式的证书形 ...

  3. BZOJ 1642: [Usaco2007 Nov]Milking Time 挤奶时间

    Description 贝茜是一只非常努力工作的奶牛,她总是专注于提高自己的产量.为了产更多的奶,她预计好了接下来的N (1 ≤ N ≤ 1,000,000)个小时,标记为0..N-1. Farmer ...

  4. Linux企业级项目实践之网络爬虫(26)——线程池

    一旦有一个抓取请求开始,就创建一个新的线程,由该线程执行任务,任务执行完毕之后,线程就退出.这就是"即时创建,即时销毁"的策略.尽管与创建进程相比,创建线程的时间已经大大的缩短,但 ...

  5. 工作随笔——spring异步处理@Async使用笔记

    @Async使用笔记 必须是public方法 必须是非static方法 方法调用的实例必须由spring创建和管理 代码示例如下: // 创建Foo类@Component class Foo { @A ...

  6. ubuntu 14.04zabbix的安装

    开始安装 64位  Ubuntu 14.04.5 LTS \n \l 安装zabbix的源,以下操作在root下进行 # wget http://repo.zabbix.com/zabbix/3.0/ ...

  7. Update openssh7.9 on centos6

    一.制作RPM安装包1)依赖安装yum install rpm-build gcc make wget openssl-devel krb5-devel pam-devel libX11-devel ...

  8. 移动端开发demo—移动端web相册(一)

    本文主要是介绍开发移动端web相册这样一案例用到的前置知识. 一.移动端样式 移动端更接近手机原生的方式. 如下是一个angular mobile的demo的例子: 移动端demo做成这样的好处: 在 ...

  9. 关于模板引擎handlebars.js基本用法

    说明:模板引擎主要针对于渲染DOM,取代了字符串拼接,用下面的代码亲测handlebars模板引擎比字符串拼接渲染DOM慢了20ms, 这里配置一个在线DEMO,简单说明下handlebars.js的 ...

  10. mysql迁移sqlserver

    数据迁移的工具有很多,基本SSMA团队已经考虑到其他数据库到SQL Server迁移的需求了,所以已经开发了相关的迁移工具来支持. 此博客主要介绍MySQL到SQL Server数据迁移的工具:SQL ...