assembly 是否可以在riscv中的两个锁上构建一个原子的“释放和获取”操作?

11dmarpk  于 2022-11-13  发布在  其他
关注(0)|答案(2)|浏览(144)

有没有可能在riscv中构建一个原子的“release-and-acquire”操作,这样就可以释放一个锁,然后立即原子地获取另一个锁?
我发现大多数riscv锁定机制是使用原子交换amoswap.w.aq实现的,但是它似乎不支持两个内存位置之间的交换,只支持内存位置和寄存器之间的交换。
我也知道riscv中存在LR/SC(加载保留/存储条件)指令,但它似乎不支持多个内存地址之间的这种事务内存方案。

aurhwmvo

aurhwmvo1#

一般来说,“原子地与内存交换内存”对于CPU来说是一件不寻常的事情。(The MC68030 is notable as one of the few historical machines that did support it.)在大多数情况下,你只需要用一个互斥体来保护这两个对象。因此,如果你需要原子地删除一个锁,并使用另一个锁,你需要第三个锁来保护这对锁。
另一种选择是将锁表示为单个机器字中的不同位或位域(如果它们适合的话)。然后,您可以使用LL/SC对来原子地旋转您需要的它们的任何组合。但这是以更高的争用为代价的;现在,正在使用任何锁的所有线程都在竞争对同一字的访问。
一些体系结构提供双字LL/SC或比较和交换,这样你实际上可以使用两个相邻的机器字(对于无锁链表等也很有用),但似乎RISC-V没有。

j8ag8udp

j8ag8udp2#

@ErikEidt在评论中问了正确的问题,帮了我的忙:
如果另一个锁不可用,它应该怎么做?在你的情景中,拥有第一个锁是否以某种方式保证了第二个锁是可用的?
我已经想清楚了,要求这样的原子“释放然后获取”操作似乎是一件奇怪的事情。
如果第一个锁A保证第二个锁B可用:

  • 那么它就等同于acquire(B); release(A);,其中acquire(B)总是成功的。(死锁也不可能发生)

如果它没有这样的保证,那么当B不可用时:

  • 假设该操作在锁A仍被持有的情况下旋转锁B,那么它又与acquire(B); release(A);相同。(可能存在死锁)
  • 如果它在释放锁A之后旋转到B,那么它所做的就是release(A); acquire(B);

我最初的意图是使用此操作来解决由于在两个锁之间切换而导致的死锁问题。但似乎所有“release-then-acquire”操作将执行的操作都与作为两个单独操作的纯获取和释放操作相同。可能需要更多地考虑我的并发设计。:\

相关问题