您好、欢迎来到现金彩票网!
当前位置:2019全年资料大全正版 > 同步操作 >

ARM体系架构下的同步操作

发布时间:2019-05-21 14:26 来源:未知 编辑:admin

  当共享资源为一内存地址时,原子操作是对该类型共享资源同步访问的最佳方式。

  随着应用的日益复杂和SMP的广泛使用,处理器都开始提供硬件同步原语以支持原子地更新内存地址。

  CISC处理器比如IA32,可以提供单独的多种原子指令完成复杂的原子操作,由处理器保证读-修改-写回过程的原子性。

  而RISC则不同,由于除Load和Store的所有操作都必须在寄存器中完成,

  如何保证从装载内存地址到寄存器,到修改寄存器中的值,再到将寄存器中的值写回内存中可以原子性的完成,便成为了处理器设计的关键。

  与LDR指令不同的是,该指令也会同时初始化exclusive monitor来记录对该地址的同步访问。例如

  会将R0寄存器中内存地址的数据,加载进R1中并更新exclusive monitor。

  STREX会根据exclusive monitor的指示决定是否将寄存器中的值写回内存中。

  如果exclusive monitor许可这次写入,则STREX会将寄存器Rm的值写回Rn所存储的内存地址中,并将Rd寄存器设置为0表示操作成功。

  如果exclusive monitor禁止这次写入,则STREX指令会将Rd寄存器的值设置为1表示操作失败并放弃这次写入。

  在这篇文章里,首先会以Linux Kernel中ARM架构的原子相加操作为例,介绍这两条指令的使用方法;

  之后,会介绍GCC提供的一些内置函数,这些同步函数使用这两条指令完成同步操作。

  在第9,10,11行,使用STREX指令尝试将修改后的值存入原来的地址,

  如果%1寄存器的值不为0,则认为exclusive monitor拒绝了本次对内存地址的访问,

  则跳转回第7行重新进行以上所述的过程,直到成功将修改后的值写入内存为止。

  该过程可能多次反复进行,但可以保证,在最后一次的读-修改-写回的过程中,没有其他代码访问该内存地址。

  输入为v(原子变量),i(要设置的值),均存放在动态分配的寄存器中。tmp用来指示操作是否成功。

  在用户态下,GCC为我们提供了一系列内置函数,这些函数可以让我们既享受原子操作的好处,

  又免于编写复杂的内联汇编指令。这一系列的函数均以__sync开头,分为如下几类:

  这一系列函数完成对ptr所指向的内存地址的对应操作,并返回操作之前的值。

  这一系列函数完成对ptr所指向的内存地址的对应操作,并返回操作之后的值。

  即如果ptr所指向的内存地址存放的值与oldval相同的话,则将其用newval的值替换。

  返回bool类型的函数返回比较的结果,相同为true,不同为false;

  为应用于Rn中的值的可选偏移量。offset只可用于 Thumb-2 指令中。 如果省略offset,则认为偏移量为 0。

  如果物理地址有共享 TLB 属性,则LDREX会将该物理地址标记为由当前处理器独占访问,并且会清除该处理器对其他任何物理地址的任何独占访问标记。

  如果物理地址没有共享 TLB 属性,且执行处理器有一个已标记但尚未访问完毕的物理地址,那么将会进行存储,清除该标记,并在Rd中返回值 0。

  如果物理地址没有共享 TLB 属性,且执行处理器也没有已标记但尚未访问完毕的物理地址,那么将不会进行存储,而会在Rd中返回值 1。

  如果物理地址有共享 TLB 属性,且已被标记为由执行处理器独占访问,那么将进行存储,清除该标记,并在Rd中返回值 0。

  如果物理地址有共享 TLB 属性,但没有标记为由执行处理器独占访问,那么不会进行存储,且会在Rd中返回值 1。

  利用LDREX和STREX可在多个处理器和共享内存系统之前实现进程间通信。

  出于性能方面的考虑,请将相应LDREX指令和STREX指令间的指令数控制到最少。

  STREX指令中所用的地址必须要与近期执行次数最多的LDREX指令所用的地址相同。

http://cpfafrance.com/tongbucaozuo/152.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有