硬件提供原子指令,如测试和设置、比较和交换、加载链接存储条件。这些是特权指令吗?也就是说,只有操作系统才能执行它们(因此需要系统调用)?
我认为他们没有特权,可以在用户空间中调用。但http://faculty.salina.k-state.edu/tim/ossg/IPC_sync/ts.html似乎另有建议。但是,futex(7)在某些条件下,可以在没有系统调用的情况下实现锁定,这意味着它必须在没有特权的情况下执行指令(如 test-and-set)。
矛盾?如果是这样,哪个是对的?
硬件提供原子指令,如测试和设置、比较和交换、加载链接存储条件。这些是特权指令吗?也就是说,只有操作系统才能执行它们(因此需要系统调用)?
我认为他们没有特权,可以在用户空间中调用。但http://faculty.salina.k-state.edu/tim/ossg/IPC_sync/ts.html似乎另有建议。但是,futex(7)在某些条件下,可以在没有系统调用的情况下实现锁定,这意味着它必须在没有特权的情况下执行指令(如 test-and-set)。
矛盾?如果是这样,哪个是对的?
那个页面是错误的。似乎声称无锁原子操作通常在 ISA 上具有特权,但事实并非如此。我从未听说过原子测试和设置或任何其他无锁操作需要内核模式。
如果是这种情况,则需要C++11 无锁原子读取-修改-写入操作才能编译为系统调用,但它们不适用于 x86、ARM、AArch64、MIPS、PowerPC 或任何其他普通 CPU . (在https://godbolt.org/上试试)。
它还会使“轻量级”锁定(它试图在没有系统调用的情况下获取锁定)变得不可能。(http://preshing.com/20111124/always-use-a-lightweight-mutex/)
普通 ISA 允许用户空间在线程之间甚至不同进程之间共享的内存上执行原子 RMW 操作。 我不知道在 x86 上为用户空间禁用原子 RMW 的机制。即使任何ISA上有这样的东西,也不是正常的操作模式。
只读或只写访问通常在所有 ISA 上的对齐位置上自然是原子的,直到一定宽度(为什么在 x86 上自然对齐的变量上的整数赋值是原子的?),但原子 RMW 确实需要硬件支持。
在 x86 上,TAS 是lock bts
,这是非特权的。(前缀的文档lock
)。x86 有多种其他原子操作可供选择,例如lock add [mem], reg/immediate
, lock cmpxchg [mem], reg
,甚至在需要返回值时lock xadd [mem], reg
实现。fetch_add
(对于'int num',num++ 可以是原子的吗?)
大多数 RISC 都有 LL/SC,包括 ARM、MIPS 和 PowerPC,以及所有旧的不再常见的 RISC ISA。
futex(2)
是系统调用。如果你调用它,它所做的一切都是在内核模式下。
它是轻量级锁定在发生争用时使用的回退机制,提供操作系统辅助的睡眠/唤醒。因此,它futex
本身并不是在用户空间中做任何事情,而是围绕构建的锁实现futex
可以避免在无争用或低争用情况下进行系统调用。
(例如,在用户空间旋转几次,以防锁定可用。)
这就是futex(7)
手册页所描述的内容。但是如果您实际上没有进行系统调用,我觉得将其称为“futex 操作”有点奇怪。我猜它是在内核代码可能代表正在等待的其他线程查看的内存上运行的,因此在用户空间代码中修改内存位置的必要语义取决于futex
.