两个CPU核心上的InterlockedExchange

时间:2013-08-06 09:28:32

标签: windows kernel interlocked

我有一个Windows 7驱动程序,我希望同步对变量的访问。我可以使用InterlockedExchange吗?

我目前对InterlockedExchange的理解是,InterlockedExchange是通过编译器内在函数完成的。这意味着,read(InterlockedExchange返回旧值)并且写入在一个时钟周期内完成。只有当变量总是通过互锁函数访问时,互锁函数才是原子的。

但在这种情况下会发生什么:

CPU1: InterlockedExchange(&Adapter->StatusVariable, 5);
CPU2: InterlockedExchange(&Adapter->StatusVariable, 3);

StatusVariable在两个CPU内核上以相同的时钟周期写入。该函数是否注意到该变量被访问并将写入推迟到不同的时钟周期?或者是否未定义写入后变量具有哪个值?变量是否也可能包含垃圾?

编辑:我在x86或x64上。

2 个答案:

答案 0 :(得分:2)

InterlockedExchange生成一个具有隐式内存屏障的xchg指令。

Intel Instruction set reference是你的朋友:)有关锁如何工作的更多信息,请参阅第8章。

来自XCHG指令:

  

交换指令交换一个或多个操作数的内容,在某些情况下,执行其他操作,例如断言LOCK信号或修改EFLAGS寄存器中的标志。

     

XCHG(交换)指令交换两个操作数的内容。该指令取代了三个   MOV指令并不需要临时位置来保存一个操作数位置的内容   其他正在加载。当内存操作数与XCHG指令一起使用时,处理器的LOCK信号为   自动断言。因此,该指令对于实现信号量或类似的数据结构非常有用   进程同步。请参阅英特尔®64和64的“多处理器管理”第8章中的“总线锁定”   IA-32架构软件开发人员手册,第3A卷,有关总线锁定的更多信息。

如果您对该参考有任何疑问,请询问。

答案 1 :(得分:1)

  

我有一个Windows 7驱动程序,我希望同步访问a   变量。我可以使用InterlockedExchange吗?

也许。也许不吧。这取决于您尝试做什么,变量代表什么以及当您说“同步访问”时您的期望是什么。

话虽如此,我怀疑答案是否定的,因为我看不出你在做什么算作同步。

  

这意味着,read(InterlockedExchange返回旧值)和   写操作在一个时钟周期内完成。

不完全是。互锁功能确保操作以原子方式进行。需要多少个时钟周期是另一个问题。忘记时钟周期。

  

只有当变量始终为时,互锁函数才是原子的   通过互锁功能访问。

这甚至意味着什么?

  

该函数是否注意到该变量被访问并推迟   写入不同的时钟周期?

更准确地说,处理器会注意到它。无论是将一个写入延迟到不同的时钟周期,您还关心什么?也许它确实如此,也许它没有。这个过程不属于你的业务。

在您的示例中,所有编译器和处理器都将保证,您需要知道的是:

    在语句InterlockedExchange(&Adapter->StatusVariable, 3);之后
  1. Adapter->StatusVariable的值将为3或5;和
  2. 在语句InterlockedExchange(&Adapter->StatusVariable, 5);之后
  3. Adapter->StatusVariable的值将为3或5。
  4. 它将具有这两个值中的一个而没有其他值。您只是无法知道它将具有哪些值,并且应该明白为什么会这样。

      

    或者是否未定义变量在写入后具有哪个值?

    这取决于你对“未定义”的定义。目前还不清楚它将具有哪两个值,但它具有35,假设在该点之后没有其他线程正在改变该值。

      

    变量是否也可能包含垃圾?

    如果“垃圾”你指的是35以外的其他内容,那么在没有任何其他代码混淆价值的情况下,答案是明确的否< / strong>即可。变量将包含值3或值5