ARM LDREX/STREX指令以及独占监控器详解
一、目的
Linux驱动开发中有一个特别重要的知识点必须掌握,即并发、竞态以及同步。
什么是并发?
多个执行单元(进程、线程、中断)同时对一个共享资源的进行访问;此处的共享资源可以是外设、内存或者软件层面的全局变量静态变量等。
什么是同步?
多个执行单元对同一个共享资源访问会引发竞态问题,导致程序运行异常;为了保证某个时刻只能有一个执行单元对共享资源进行操作,就需要进行同步(即独占访问,即A在访问资源时,B只能忙等待或或者休眠;只有A释放其对共享资源的占用后,B才能访问)。
情景分析

上图中每条连线都代表并发可能发生的情景。
进程可能由于其时间片段用完发生调度,也有可能直接被更高优先级的进程抢占执行;中断也可以打断进程的执行。
在SMP多核系统中多个CPU都可以对外设或者内存进行访问,所以并发的情景更加频繁。

在单核支持抢占的系统中,进程A的执行流程可能被进程B打断;进程A的执行流程也可能被中断本身打断,故在单核支持抢占的系统中,并发也是现实存在的问题。
针对并发问题,Linux内核中提供了多种同步手段来协调资源的访问,例如关中断(单核简单系统中可用)、原子操作、自旋锁、信号量、互斥锁、完成量等。
但是我们细看其代码时,我们会发现在ARM平台中原子操作或者其他同步机制都需要LDREX/STREX指令的参与(还有更重要的一个知识点--屏障指令)。
本篇的目的就是帮助大家深入理解这两个指令的作用、实现原理以及应用。
二、介绍
参考资料
https://developer.arm.com/documentation/dht0008/a/arm-synchronization-primitives/exclusive-accesses/ldrex-and-strex?lang=en
LDREX/STREX是ARM架构上的同步原语,属于硬件层面的同步机制。同步发生在当共享资源某个时刻只能被一个执行单元访问时;共享资源可以是内存、外设设备;执行单元可以是处理器、进程或者线程;
一般是通过以原子方式(原子是最小的不可分割的)修改代表资源状态的一个变量来实现(同步);修改操作只会有两个结果,要么成功,要么失败;并且对所有的同时访问这个变量的执行单元都可见。
在简单系统中可以通过开关中断的方式实现;在多任务和多核系统中开关中断可能未必是个有效的方法,频繁的开关中断会影响系统的实时处理和调度,甚至有可能就是一个BUG所在。
LDREX/STREX这两个指令配合独占监控器(独占监控器会跟踪独占内存访问)可以实现原子地更新内存数据。
LDREX指令说明

LDREX指令从内存中加载一个字(word),并且初始化独占监控器的状态用来跟踪同步操作。
LDREX R1, [R0]上面的代码片段从R0寄存器表示的地址中读取一个字,存放在R1寄存器中,并且更新独占监控器。
STREX指令说明

STREX指令将存储一个字到内存中,但是这个存储指令是有条件的;如果独占监控器允许这个存储操作,那么对应的内存地址就会更新,并且将返回值0保存在目标寄存器中,代表此次操作成功;如果独占监控器不允许,那么就不会更新独占监控器,并且将返回值1保存在目标寄存器中,代表此次操作失败。
基于上述逻辑,我们就可以实现条件执行语句,根据STREX不同的结果进行不同的操作。
独占监控器
在上面的描述中我们提到独占监控器,独占监控器是一种简单的状态机,其存在两种状态:打开或者独占。为了实现多个处理器间的同步,一般会存在两类独占监控器:本地监控器和全局监控器。
对非共享内存的独占访问只检查本地监控器;对共享内存的独占访问会同时检查本地和全局监控器

如果我们访问共享资源,例如上图中的Memory B,那么当CPU0访问B时,CPU0的本地独占监控器会标记为已被独占,同时全局独占监控器也会标记为已被独占(全局监控器会监控多个CPU对共享资源的访问)
上图中Memory A只会被CPU0访问,但是CPU0可能内部多个进程都会访问Memory A。
独占监控器情景分析
CPU0访问Memory A的情形
时间 | 进程1 | 进程2 |
T1 | LDREX | |
T2 | ... | LDREX |
T3 | STREX | ... |
T4 | STREX |
T1时刻进程1调用LDREX,此时本地监控器标记为已独占;
T2时刻进程2也调用LDREX,此时也会标记本地监控器为已独占;
T3时刻进程1调用STREX,此时由于本地监控器是独占状态,所以进程1的STREX操作成功同时清除本地独占器的独占状态;
T4时刻进程2调用STREX,但是此时本地独占器为Open状态,故此处存储操作不成功;所以进程2必须重新通过LDREX指令去获取内存值去判断。
CPU0和CPU1访问Memory B的情形和上述基本类似,此处不再赘述,只要特别注意的是,对于共享内存的访问,会更新全局监控器,STREX执行完毕后本地和全局独占监控器都会复位为Open状态。
互斥锁实现
基于LDREX/STREX这样的硬件特性,我们可以实现互斥锁或者信号量


注意lock_mutex/unlock_mutex函数中的DMB指令的使用
实现信号量


我们在实现互斥锁或者信号量时可以根据业务需要,可以永久等待或者超时等待,或者完全不等待仅查询是否可以获取到锁或者信号量。
至此,本篇的知识点就介绍完毕,记得点赞+收藏。
相关文章:
ARM LDREX/STREX指令以及独占监控器详解
一、目的Linux驱动开发中有一个特别重要的知识点必须掌握,即并发、竞态以及同步。什么是并发?多个执行单元(进程、线程、中断)同时对一个共享资源的进行访问;此处的共享资源可以是外设、内存或者软件层面的全局变量静态…...
吉林大学 程序设计基础 2022级 实验复盘 2.23
本人能力有限,发出只为帮助有需要的人。 以下为实验课的复盘,内容会有大量失真,请多多包涵。 此次实验限时一个小时,时间很紧张,很多内容可能并不准确。 1.输出有规律的字母串 输入输出如下; 输入&…...
Linux系列 常用命令(目录和文件管理)vi和vim 编辑使用,(笔记)
作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页 目录 前言 一.常用命令(目录和文件管理) 1.查看文件内容 2.统计…...
OpenCV入门(一)Python环境的搭建
OpenCV入门(一)Python环境的搭建 因为有点Python基础,并且Python是比较好入门的编程语言,所以,机器视觉后面打算在Python这个平台下进行。 Windows平台OpenCV的Python开发环境搭建 1、Python 的下载与安装 Python是…...
3.查找算法:顺序查找和二分查找
查找查找,是指在一些数据元素中,通过一定的方法找出与给定关键字相同的数据元素的过程。列表查找(线性表查找):从列表中查找指定元素输入:列表,待查找元素输出:元素下标(…...
攻不下dfs不参加比赛(七)
标题 为什么练dfs题目总结重点为什么练dfs 相信学过数据结构的朋友都知道dfs(深度优先搜索)是里面相当重要的一种搜索算法,可能直接说大家感受不到有条件的大家可以去看看一些算法比赛。这些比赛中每一届或多或少都会牵扯到dfs,可能提到dfs大家都知道但是我们为了避免眼高手…...
精确光度预测计算工具:AGi32 Crack
什么是AGi32? AGi32首先是一种用于精确光度预测的计算工具:一种技术工具,可以计算任何情况下的照度,协助灯具放置和瞄准,并验证是否符合任意数量的照明标准。 然而,要增强对光度学结果的理解,还…...
47个SQL性能优化技巧,看到就是赚到
1、先了解MySQL的执行过程 了解了MySQL的执行过程,我们才知道如何进行sql优化。 (1)客户端发送一条查询语句到服务器; (2)服务器先查询缓存,如果命中缓存,则立即返回存储在缓存中的…...
汇川SV660N与基恩士 KV7500 控制器调试说明
1. 伺服相关部分配置 1.1 伺服相关版本 SV660N 试机建议使用“SV660N-Ecat_v0.09.xml”及以上设备描述文件。 SV660N 单板软件版本建议为“H0100901.4”及更高版本号。 1.2 相关参数说明 SV660N 对象字典中 60FD 的含义较 IS620N 有所更改:bit0、1、2 分别为负限位…...
图观 | ChatGTP是如何通过知识图谱回答问题的?
文/Emma Z1950年,图灵发表了具有里程碑意义的论文《计算机器与智能》(Computing Machinery and Intelligence),提出了一个关于机器人的著名判断原则——图灵测试,也被称为图灵判断,它指出如果第三者无法辨别…...
Mysql的索引
为什么写这篇文章呢~最近在梳理公司的数据库,在查看表结构的时候发现了这个 CREATE TABLE esp_5_N (ID int(11) NOT NULL AUTO_INCREMENT,pId int(11) DEFAULT NULL,EsFileId varchar(32) DEFAULT NULL,obligate1 varchar(45) DEFAULT NULL,obligate2 varchar(45) …...
计算机的发展
个人简介:云计算网络运维专业人员,了解运维知识,掌握TCP/IP协议,每天分享网络运维知识与技能。个人爱好: 编程,打篮球,计算机知识个人名言:海不辞水,故能成其大;山不辞石…...
理解Spring中的依赖注入和控制反转
依赖注入(Dependency Injection)是一种面向对象编程的设计模式,用于解决对象之间的依赖关系。它的基本思想是将对象的创建和管理工作交给容器来完成,而不是在应用程序中手动创建和管理对象,从而达到松耦合、易维护、易…...
XXL-JOB
XXL-JOB介绍 XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。 官网:https://www.xuxueli.com/xxl-job/ 文档:分布式任务调度…...
「牛客网C」初学者入门训练BC134,BC136
🐶博主主页:ᰔᩚ. 一怀明月ꦿ ❤️🔥专栏系列:线性代数,C初学者入门训练 🔥座右铭:“不要等到什么都没有了,才下定决心去做” 🚀🚀🚀大家觉不错…...
华为OD机试题【翻转单词顺序】用 C++ 进行编码 (2023.Q1)
最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明翻转单…...
4.Spring【Java面试第三季】
4.Spring【Java面试第三季】前言推荐4.Spring27_Aop的题目说明要求Spring的AOP顺序AOP常用注解面试题28_spring4下的aop测试案例业务类新建一个切面类MyAspect并为切面类新增两个注解:spring4springboot1.5.9pom测试类29_spring4下的aop测试结果aop正常顺序异常顺序…...
ZLibrary使用说明-Zlirbrary
ZLibrary使用说明如果您是一位书虫,那么ZLibrary是一个值得一试的网站。该网站提供了大量的免费电子书籍,涵盖了各种不同的主题和类别。下面是一些有关如何使用ZLibrary的详细说明:第1步:访问ZLibrary网站要使用ZLibraryÿ…...
TwinCAT3第三方伺服电机——汇川SV660N使用
目录 一、第三方伺服在TC3中配置和使用 二、xml文件拷贝 编辑 三、IO中扫描伺服 四、工程测试 五、汇川伺服参数设置说明 一、第三方伺服在TC3中配置和使用 在倍福控制系统中使用第三方伺服可以参见本人另一篇博客,有详细教程说明。本文仅仅对SV660N伺服设置…...
进制转换(二进制,八进制,十进制,十六进制)涵盖整数与小数部分,内容的图片全为手写【详细图解】
各种进制之间的相互转换1. 各进制表示数1.1 数码1.2 基数1.3 位权2. 十进制转换为其他进制2.1 整数部分2.2 小数部分3. 其他进制转换为十进制4. 二进制转换为八进制5. 二进制转换为十六进制6. 八进制转换为十六进制1. 各进制表示数 二进制:0,1逢二进一 八…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...
