gpt4 book ai didi

c - xv6: 不使用 ticks 锁直接读取 ticks?

转载 作者:太空宇宙 更新时间:2023-11-03 23:37:30 27 4
gpt4 key购买 nike

我正在 Xv6 上做操作系统类(class)的作业.我需要为其创建时间、终止时间、休眠时间等实现一个进程的数据状态结构...

到目前为止,我决定直接使用 ticks 变量而不使用 tickslock,因为使用锁并降低系统速度似乎不是一个好主意一个低优先级的目标。

由于 ticks 变量只像这样使用:ticks++,有没有办法尝试检索当前的 ticks 数并得到错误的数字?

我不介意在 +-10 个刻度内得到一个错误的数字,但有没有办法让它真正消失。就像当数字 01111111111111111 递增时,它需要更改 2 个字节。所以我的问题是,CPU 是否有可能分阶段存储数据,而另一个 CPU 将能够在存储操作开始和完成之间获取该内存位置中的数据?

所以在我看来,如果编译器将创建一条 mov 指令或一条 inc 指令,我想知道的是存储操作是否可以在两者之间看到它的开始和结束。

最佳答案

在 asm 中没有问题:在 x86 上用一条指令完成的对齐加载/存储在 qword(8 字节)宽度内是原子的。 Why is integer assignment on a naturally aligned variable atomic on x86?

(在 486 上,保证只针对 4 字节对齐的值,对于 386 甚至可能不是,所以这可能就是 Xv6 使用锁定的原因?我不确定它是否应该是多核安全的386;我的理解是罕见的 386 SMP 机器没有完全实现现代 x86 内存模型(内存排序等)。)

但 C 不是 asm。 同时使用来自多个“线程”的普通非原子 变量是未定义的行为,除非所有线程都只读取。这意味着编译器可以假定普通 C 变量不会被其他线程异步更改。

在 C 的循环中使用 ticks 将使编译器 read it once and keep using the same value repeatedly .您需要像 Linux 内核使用的 READ_ONCE 宏,例如*(volatile int*)&ticks。或者简单地将其声明为 volatile unsigned ticks;


对于一个足够窄以适合一个整数寄存器的变量,可以安全地假设一个理智的编译器将使用单个双字存储来编写它,无论是 mov 还是内存目标 incadd dword [mem], 1。 (不过,您不能假设编译器将使用内存目标 inc/add,因此您不能依赖于中断方面的增量是单核原子的。)

对于一个作者和多个读者,是的,只要他们使用 volatile,读者就可以简单地读取它而无需任何类型的锁定。

即使在可移植 ISO C 中,volatile sig_atomic_t当由信号处理程序编写并由运行信号处理程序的线程读取时,对安全工作的保证非常有限。 (不过,不一定是 其他 线程:在 ISO C 中,volatile 不会避免数据争用 UB。但实际上在 x86 上使用非恶意编译器时没问题。)

(POSIX 信号相当于用户空间的中断。)

另见 Can num++ be atomic for 'int num'?

对于一个线程将更宽的计数器分成两半,您通常会使用 SeqLock。对于 1 个写入器和多个读取器,没有实际的锁定,如果写入与读取重叠,则由读取器重试。参见 Implementing 64 bit atomic counter with 32 bit atomics

关于c - xv6: 不使用 ticks 锁直接读取 ticks?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55345856/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com