更新时间:2021-07-08 GMT+08:00
分享

概述

基本概念

在支持多任务的操作系统中,修改一块内存区域的数据需要“读取-修改-写入”三个步骤。然而同一内存区域的数据可能同时被多个任务访问,如果在修改数据的过程中被其他任务打断,就会造成该操作的执行结果无法预知。

使用开关中断的方法固然可以保证多任务执行结果符合预期,但这种方法显然会影响系统性能。

ARMv6架构引入了LDREX和STREX指令,以支持对共享存储器更缜密的非阻塞同步。由此实现的原子操作能确保对同一数据的“读取-修改-写入”操作在它的执行期间不会被打断,即操作的原子性。

运作机制

Huawei LiteOS通过对ARMv6架构中的LDREX和STREX进行封装,向用户提供了一套原子操作接口。

  • LDREX Rx, [Ry]

    读取内存中的值,并标记对该段内存为独占访问:

    • 读取寄存器Ry指向的4字节内存数据,保存到Rx寄存器中。
    • 对Ry指向的内存区域添加独占访问标记。
  • STREX Rf, Rx, [Ry]

    检查内存是否有独占访问标记,如果有则更新内存值并清空标记,否则不更新内存:

    • 有独占访问标记
      1. 将寄存器Rx中的值更新到寄存器Ry指向的内存。
      2. 标志寄存器Rf置为0。
    • 没有独占访问标记
      1. 不更新内存。
      2. 标志寄存器Rf置为1。
  • 判断标志寄存器
    • 标志寄存器为0时,退出循环,原子操作结束。
    • 标志寄存器为1时,继续循环,重新进行原子操作。

相关文档