Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
互斥锁mutex互斥量
原子指令-原子操作_atomic
常用芯片构架的原子指令
发布于 2022-05-16 22:14:56 浏览:1187
订阅该版
[tocm] 原子指令需求来源和作用可以自行查阅相关文章,这里就不重复了。 ## ARMV6之前 ARMV6之前原子指令是`SWP`指令,SWP的指令格式例如以下: `SWP Rd, Rm, [Rn] ; rd=[rn], [rn]=rm` - Rd寄存器是目的寄存器。从存储器中读到的值存放于此寄存器中 - Rm寄存器是操作数。会将此寄存器中的值存放于存储单元中 - [Rn]是寄存器间接寻址,Rn保存的是某个存储单元的地址 SWP是swap的缩写,在向目标写入一个值的同时,把原来的值取回来。 在硬件实现机制上,查到的信息是: - 在单核时,因单条指令不能再分割,所以这个操作是安全的。如果此时有来了中断,中断也相应被延迟一些周期。 - 在多核心时,在执行SWP期间,禁止所有人访问存储器。如果其它核心此时并不会访问目标地址,这样就白等了,拖慢了性能。不过我暂时也没见过ARMv6以前的多核芯片。 在用法上,大家可以对要写入的值做个约定。 这样通过判断取回来的值,是否符合预期,就能知道是否会其它人干扰打断。 这是使用SWP指令实现的锁,参见: - https://developer.arm.com/documentation/dht0008/a/CJHBGBBJ ``` EXPORT lock_mutex_swp lock_mutex_swp PROC LDR r2, =locked SWP r1, r2, [r0] ; Swap R2 with location [R0], [R0] value placed in R1 CMP r1, r2 ; Check if memory value was 'locked' BEQ lock_mutex_swp ; If so, retry immediately BX lr ; If not, lock successful, return ENDP EXPORT unlock_mutex_swp unlock_mutex_swp LDR r1, =unlocked STR r1, [r0] ; Write value 'unlocked' to location [R0] BX lr ENDP ``` 但也有讨论说,使用SWP不如直接关中断 https://www.zhihu.com/question/269468167 关于指令功能进一步说明: https://developer.arm.com/documentation/ddi0406/c/Application-Level-Architecture/Instruction-Details/Alphabetical-list-of-instructions/SWP--SWPB ## ARMV6之后 ARMV6之后的原子指令是`LDREX/STREX`,从前缀来看就是对`LDR/STR`这对存储器访问指令的改造。 所有内存单元的状态默认为`Open Access state` `LDREX Rx ,[Rz]` 将Rz寄存器指向的内存单元处的值读取出来放到Rx寄存器中,并标记[Rz]单元处的内存单元为`Exclusive Access state` `STREX Rx, Ry, [Rz]` - 将Ry寄存器中的值放到Rz指向的内存单元处, - 如果Rz内存单元的状态为`Exclusive Access state`,则Rx的值将会被赋值为0,指令成功。 - 而如果Rz内存单元的状态为`Open Access state`的话,Rx的值将会被赋值为1,并且Ry的值也不会被加载到Rz指向的内存单元中。也就是指令失败。 相比SWP指令来说,不再有锁定操作,而是仅标记被独占的地址。 如果其它人不访问相同的地址,则不会有任何影响。 如果大家访问相同的地址,则有可能失败,但会有状态指示。 这样有可能会被同时访问到的变量,只需要使用这对原子指令,并检查返回状态,当有失败后再重试就行了。 使用上的细节,需要关注硬件实现上的`local monitor`和`global monitor`。表现在软件上面,就是设置对应的内存属性。 - shareable memory (该memory是多个CPU之间共享的,可能会被多个CPU同时访问) - Non-shareable memory(该memory不是多个CPU之间共享的,只会被一个CPU访问) 相关参考 - https://developer.arm.com/documentation/ddi0406/c/Application-Level-Architecture/Instruction-Details/Alphabetical-list-of-instructions/LDREX - https://developer.arm.com/documentation/ddi0406/c/Application-Level-Architecture/Instruction-Details/Alphabetical-list-of-instructions/STREX ## RISC-V 参考链接:[RISC-V 原子指令介绍](https://tinylab.org/riscv-atomics/) RISC-V的原子指令在`A`(Atomic)扩展中实现,主要由2部分组成。 - `LR/SC` 指令 - AMO(Atomic Memory Operations)指令 ### LR/SC `LR/SC` 指令和ARM的`LDREX/STREX`指令属于同一类。 实现原理依然是地址标记,没有锁。多核及异构时,不会拖累其它核心的速度。 `LR`指令是`Load Reserved`的缩写,读取保留。 指令格式:`lr.{w/d}.{aqrl} rd, (rs1)`,其中`w/d`分别对应`32/64`位版本。 lr 指令是从内存地址 rs1 中加载内容到 rd 寄存器。 然后在 rs1 对应地址上设置保留标记(reservation set)。 `SC`指令是`Store Conditional`的缩写,条件存储。 指令格式:`sc.{w/d}.{aqrl} rd, rs2, (rs1)`,其中 w/d 分别对应 32 位/64 位版本。 sc 指令在把 rs2 值写到 rs1 地址之前,会先判断 rs1 内存地址是否有设置保留标记, - 如果设置了,则把 rs2 值正常写入到 rs1 内存地址里,并把 rd 寄存器设置成**0**,表示保存成功。 - 如果 rs1 内存地址没有设置保留标记,则不保存,并把 rd 寄存器设置成**非零值**表示保存失败。 注意: - 不管成功还是失败,sc 指令都会把当前 hart 保留的所有保留标记全部清除。 - 对于 lr/sc 指令,要求 rs1 寄存器中的地址是按宽度对齐的,比如 lr.w 要求 4 字节对齐,sc.d 要求 8 字节对齐。否则会触发非对齐异常。 如果在 sc 指令之前,当前 hart 观察到了对应内存地址被其他 hart 写了,则 sc 指令会失败。相当于保留标记失效了。如果对应内存地址被外部设备(非 hart)或者总线写了,外部设备需要主动把写范围内的保留标记清除,不在写入范围的字节不需要清除保留标记。 RISC-V 对 LR 和 SC 之间的指令是有限制的,一个是 LR 和 SC 之间最大只能包含 16 个指令,另外这些指令只能使用基础整数指令集(指令集 “I”,不包含内存访问指令,跳转指令,fence 和 system 指令)。具体可以参考 Spec 10.3 章节。如果违反了这些限制,LR/SC 指令的效果是不受约束的,可能在一些芯片实现上能保证原子性,在另外一些芯片实现上不能保证。 ### AMO AMO 是 Atomic Memory Operation 的缩写。AMO 指令有如下几个: | AMO指令 | 说明 | | ---------- | ---------------------- | | AMOSWAP | 原子交换指令 | | AMOADD | 原子加法指令 | | AMOAND | 原子按位与指令 | | AMOOR | 原子按位或指令 | | AMOXOR | 原子按位异或指令 | | AMOMAX | 原子有符号取最大值指令 | | AMOMAXU | 原子无符号取最大值指令 | | AMOMIN | 原子有符号取最小值指令 | | AMOMINU | 原子无符号取最小值指令 | ## Other
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
aozima
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
文章
28
回答
4480
被采纳
381
关注TA
发私信
相关文章
1
互斥量操作,关中断时间长
2
互斥量不能在中断例程中使用的原因
3
互斥量例程中线程优先级的疑问
4
互斥量释放失败是什么原因?
5
线程和中断如何互斥?
6
关于互斥量优先级的问题
7
线程和中断如何互斥,第二篇
8
rtt stable2.0.x mutex
9
有什么避免中断包含mutex的技巧呢
10
挂载在操作系统上的文件系统操作,需要用互斥锁防止多线程操作问题吗?
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
freemodbus
PWM
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
中断
编译报错
Debug
SFUD
rt_mq_消息队列_msg_queue
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
踩姑娘的小蘑菇
4
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
Ryan_CW
4
个答案
1
次被采纳
xiaorui
1
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
5
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
Woshizhapuren
1
篇文章
5
次点赞
YZRD
1
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部