我正在阅读Allan Cruse code的smphello.s代码

在接下来的部分中,他尝试为每个处理器设置堆栈段。

关键是他在here中对xadd的描述中使用xadd而不使用锁前缀。可能有一个锁前缀。

这是一个错误还是可以吗?为什么?

# setup an exclusive stack-area for this processor
mov  $0x1000, %ax   # paragraphs in segment
xadd %ax, newSS     # 'atomic' xchg-and-add
mov  %ax, %ss       # segment-address in SS
xor  %esp, %esp     # top-of-stack into ESP

最佳答案

没有xaddlock是原子wrt。在该内核上中断,但不打扰。在其他内核(或DMA)上运行的代码。与xchg以外的所有其他内存目标RMW一样。参见this answer,它涵盖了cmpxchg的相同问题。
如果此代码在多个内核上同时运行,则2个或更多内核可以读取newSS的相同值,从而有效地减少增量,并将相同的ss:esp分配给两个内核。或者,一个存储可能会被碰巧是顺序的其他内核延迟跨多个xadd进行延迟,从而将计数器“倒回”到后来加载所看到的某个先前值。或任何问题的组合。 Can num++ be atomic for 'int num'?
假设newSS对齐,则装入和存储分别是原子的,但不会形成原子的RMW。
如果同时唤醒多个内核(是否可以广播IPI?),这似乎是一个真正的问题。如果不是这样,则每个xadd可能会在下一个内核到达此代码之前完成。 (包括将存储提交到L1d缓存的存储;在全局范围内可见。)但这只是“工作要做”的行为,除非内核唤醒功能在唤醒另一个内核之前等待一个内核的回音。
如果要匹配有关原子增量的注释,则肯定需要lock xadd是原子wrt。如果线程从不并发运行,则只能通过单个内核上的上下文切换来进行中断。 (例如,主线程与信号处理程序或同一内核上的中断处理程序之间的原子性)。但是,由于这被称为smphello.s,因此单处​​理器假设似乎不太可能。

关于汇编:xadd指令需要锁定吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30130752/

10-11 06:45