作者:静越家家619 | 来源:互联网 | 2022-12-05 20:57
硬件提供原子指令,如测试和设置,比较和交换,负载链接存储条件.这些特权指示吗?也就是说,只能操作系统执行它们(因此需要系统调用)?
我认为他们没有特权,可以在用户空间中调用.但http://faculty.salina.k-state.edu/tim/ossg/IPC_sync/ts.html似乎另有建议.但是,在某些条件下,futex(7)可以在没有系统调用的情况下实现锁定,这意味着它必须在没有特权的情况下执行指令(如测试和设置).
矛盾?如果是这样,哪个是对的?
1> Peter Cordes..:
那页错了.它似乎声称无锁原子操作一般在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)
是一个系统调用.如果你调用它,它所做的一切都是在内核模式下.
它是由重量轻的情况下,锁定用的回退机制存在是争用,它提供了OS辅助睡眠/觉醒.因此,它futex
本身并不能在用户空间中做任何事情,而是围绕锁定实现futex
可以避免在无竞争或低争用情况下进行系统调用.
(例如,在锁定可用的情况下,在用户空间中旋转几次.)
这是futex(7)
手册页描述的内容.但是如果你实际上没有进行系统调用,我觉得把它称为"futex操作"有点奇怪.我猜它是在内存代码可能会代表正在等待的其他线程查看的内存上运行的,因此用于修改用户空间代码中的内存位置的必要语义取决于futex
.
@ flow2k:是的,用户空间中的原子RMW.但是`futex(7)`正在记录如何围绕`futex(2)`构建锁或其他操作的一般概念.除了系统调用包装器之外,没有名为`futex()`的库函数; 如果有它将被称为`futex(3)`.无论如何是的,这个答案的重点是`futex(2)`是你如何睡觉,如果你发现锁已经在像这个x86 asm spinlock(在用户空间中工作)的实现中采取:[通过内联锁定内存操作组件(/sf/ask/17360801/46263)