Question

I have a Windows 7 driver where I want to synchronize access to a variable. Can I use InterlockedExchange for it?

My current understanding of InterlockedExchange is, that InterlockedExchange is done via compiler intrinsics. That means, the read (InterlockedExchange returns the old value) and the write is done in one clock cycle. The interlocked functions are atomic only when the variable is always accessed via an interlocked function.

But what happens in this case:

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

StatusVariable is written in the same clock cycle on two CPU cores. Does the function notice that the variable is accessed and defer the write to a different clock cycle? Or is it undefined which value the variable has after the write? Is it also possible that the variable contains garbage?

Edit: I am on x86 or x64.

Was it helpful?

Solution 2

I have a Windows 7 driver where I want to synchronize access to a variable. Can I use InterlockedExchange for it?

Maybe. Maybe not. It depends on what you are trying to do, what the variable represents and what your expectations are when you say "synchronize access".

With that said, I suspect the answer is no because I can't see how what you are doing counts as synchronization.

That means, the read (InterlockedExchange returns the old value) and the write is done in one clock cycle.

Not exactly. The interlocked functions ensure that the operation happens atomically. How many clock cycles that takes is another issue. Forget about clock cycles.

The interlocked functions are atomic only when the variable is always accessed via an interlocked function.

What does that even mean?

Does the function notice that the variable is accessed and defer the write to a different clock cycle?

It's more accurate to say that the processor notices, which it does. Whether it defers one write to a different clock cycle, what do you care? Maybe it does, maybe it doesn't. It's none of your business what the process does.

All the compiler and processor will guarantee in your example and all that you need to know is that:

  1. after the statement InterlockedExchange(&Adapter->StatusVariable, 3); the value of Adapter->StatusVariable will either be 3 or 5; and
  2. after the statement InterlockedExchange(&Adapter->StatusVariable, 5); the value of Adapter->StatusVariable will either be 3 or 5.

It will have one of those two values and no other values. You just cannot know which of those values it will have and it should be obvious to see why that is.

Or is it undefined which value the variable has after the write?

That depends on your definition of "undefined" I guess. It's unclear which of the two values it will have, but it have either 3 or 5 assuming no other threads are changing the value after that point.

Is it also possible that the variable contains garbage?

If by 'garbage' you mean something other than either 3 or 5 then, in the absence of any other code that messes with the value, the answer is an unequivocal no. The variable will contain either the value 3 or the value 5.

OTHER TIPS

InterlockedExchange generates a xchg instruction that has an implicit memory barrier.

The Intel Instruction set reference is your friend :) See Chapter 8 for more information on how locks work.

From the XCHG instruction:

The exchange instructions swap the contents of one or more operands and, in some cases, perform additional operations such as asserting the LOCK signal or modifying flags in the EFLAGS register.

The XCHG (exchange) instruction swaps the contents of two operands. This instruction takes the place of three MOV instructions and does not require a temporary location to save the contents of one operand location while the other is being loaded. When a memory operand is used with the XCHG instruction, the processor’s LOCK signal is automatically asserted. This instruction is thus useful for implementing semaphores or similar data structures for process synchronization. See “Bus Locking” in Chapter 8, “Multiple-Processor Management,”of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A, for more information on bus locking.

If you have any questions about the reference just ask.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top