下表包含锁的ARM汇编代码。
try: MOV R3,#1
SWP R2,R3,[R1,#0]
CMP R2,#1
BEQ try
LDR R4,[R2,#0]
ADD R3,R4,#1
STR R3,[R2,#0]
SWP R2,R3,[R1,#0]
我的问题是,当R2等于1时,分支回来的目的是什么?根据我的理解,如果这个分支执行,那么SWP操作出了问题,但我不知道细节。
答案 0 :(得分:3)
在没有更高级别的上下文的情况下推断确切的细节有点困难,但这看起来可能是某种票证锁定/信号量/原子增量。似乎r1
保存了一个指向原子数据的变量的地址,该变量本身就是互斥体:
try: MOV R3,#1
SWP R2,R3,[R1,#0]
此时,我们将值1原子地存储到r1
指向的位置,并将其中的值检索到r2
。现在有两种可能性:要么它已经包含1,在这种情况下swp
实际上没有改变任何东西,或者它包含不同的值。
CMP R2,#1
BEQ try
如果之前的互斥锁值 1,那么这意味着当前正在进行锁定:想象这个代码的第二个副本并行运行但稍后 - 第一个人将换入1,所以第二个人会看到它再试一次,在r1
位置旋转,直到它再次包含1以外的东西。如果它不是1,那么互斥锁 无人认领,但凭借swp
,的值现在 1,所以我们持有互斥锁并且可以继续。
LDR R4,[R2,#0]
ADD R3,R4,#1
STR R3,[R2,#0]
这意味着现在在r2
中的“无人认领”互斥量值实际上也是指向感兴趣数据的指针:我们增加它,知道这里的读取 - 修改 - 写入是有效原子的互斥体。
SWP R2,R3,[R1,#0]
......在这里我不知道 * 。将递增的数据交换回互斥锁本身似乎没有多大意义 - 如果它不是1那么它似乎会释放互斥锁,但“某些值+ 1”似乎不太可能是有效的4 -byte-aligned指针是我们(或系统中的其他代理)现在再次运行此代码。我只能想象这个片段是更复杂的事情的不完整部分。
*为了简单地发布我到目前为止想到的互斥锁,我希望写回r2
,而不是r3
。