【问题标题】:why is this a spinlock为什么这是一个自旋锁
【发布时间】:2017-02-14 01:14:59
【问题描述】:

试图理解屏障的以下实现。目标是_entry只能输入一次。我唯一没有得到的部分是%rip的使用。如果mutex(%rip)=0 显然它会旋转,但这是为什么呢?

.section data
mutex:
    .long 0

.section text
...
_entry:
    xor %rax, %rax
    xchgl mutex(%rip), %rax
    cmp %rax, 0
    jnz _entry

【问题讨论】:

  • 它只是对位置无关代码使用 rip-relative 寻址。如果 PIC 不是必需的,那么绝对寻址的工作原理相同。 PS:虽然它坏了,你想将它设置为1 而不是0。更不用说它甚至不会组装,因为您无法将long 加载到%rax
  • @Jester 所以mutex(%rip)mutex 相同,还是实际上是针对下一条指令的第一个字节?
  • 是一样的(会访问mutex),但是汇编器会生成一个相对于机器码中下一条指令的偏移量。
  • 我明白了。这很有意义。

标签: assembly x86 att


【解决方案1】:

这是一个自旋锁,因为它基本上是:

  1. 保持循环而不调用“yield”系统调用(换句话说,它不要求上下文切换)
  2. 使用“原子”操作来确保“锁定变量”具有所需的值,以便打破循环。

mutex(%rip) 是 RIP 相对(相对指令指针)寻址。这只是一个变量。可以是任何其他变量。

这个的伪代码是这样的:

_entry:
    x = 0;
    swap(mutex, x);
    if (x != 0)
        goto _entry;

但要突出显示swap(),即xchg(交换操作)。反过来,它是一个原子操作。这保证了 2 个不同的线程不会同时修改这个“锁变量”(mutex)。

作为额外的有用信息:

  • 为什么它不是互斥锁?因为它不会为操作系统中的上下文切换调用系统调用。
  • 这是否意味着没有上下文切换发生?不,这不是真的。上下文切换无论如何都会发生,但是它将发生在操作系统自己决定的时间,而不是这个例程调用的显式。操作系统对每个线程都有一个最大限制。

注意:在本例中,“锁定变量”称为mutex。但实际上这取决于您使用的词汇。大多数情况下,这不会被视为“互斥体”。锁可以通过互斥锁或自旋锁或互斥锁+自旋锁的混合来完成。但上面的例子不是混合的东西。变量名应该是mutex之外的其他名称。

【讨论】:

  • OP 的问题似乎是 RIP 在一条指令中的全部内容。也许我误解了他的意思,但他确实说 我唯一不明白的部分是使用 %rip
  • 另外,正如我所指出的,将0 写入其中不会使其成为互斥体......它的值永远不会改变,因此每个人都可以随时进入临界区。互斥量不大;)
猜你喜欢
  • 1970-01-01
  • 2010-12-29
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
  • 2011-06-12
  • 2021-09-24
  • 1970-01-01
  • 2011-08-17
相关资源
最近更新 更多