views:

2121

answers:

5

I came across the function InterlockedExchange and was wondering when I should use this function. In my opinion, setting a 32 Bit value on an x86 processor should always be atomic?
In the case where I want to use the function, the new value does not depend on the old value (it is not an increment operation). Could you provide an example where this method is mandatory (I'm not looking for InterlockedCompareExchange)

+4  A: 

InterlockedExchange is both a write and a read -- it returns the previous value.

This is necessary to ensure another thread didn't write a different value just after you did. For example, say you're trying to increment a variable. You can read the value, add 1, then set the new value with InterlockedExchange. The value returned by InterlockedExchange must match the value you originally read, otherwise another thread probably incremented it at the same time, and you need to loop around and try again.

Jason Cohen
In this case, I would use InterlockedCompareExchange, because the check whether the value was still the original one is done by the method already.
EFrank
Or just InterlockedIncrement
Mo Flanagan
+2  A: 

As well as writing the new value, InterlockedExchange also reads and returns the previous value; this whole operation is atomic. This is useful for lock-free algorithms.

(Incidentally, 32-bit writes are not guaranteed to be atomic. Consider the case where the write is unaligned and straddles a cache boundary, for instance.)

moonshadow
It would be atomic from the standpoint of software running on the processor, but not from the standpoint of hardware sitting on the bus.
Brian Knoblauch
Would it be atomic from the POV of software running on another core? What about a write that straddles a page boundary and triggers a fault?It's been years since I did any low-level x86 coding, guess I may be lying :/
moonshadow
+2  A: 

Setting a 32-bit value is atomic, but only if you're setting a literal.

b = a is 2 operations:

mov         eax,dword ptr [a] 
mov         dword ptr [b],eax

Theoretically there could be some interruption between the first and second operation.

Gerald
And if there would be some interruption, then what - it will take a little bit longer, but the value in eax will not change. The real point of InterlockedExchange is that it is atomic read and write.
Suma
+4  A: 

In a multi-processor or multi-core machine each core has it's own cache - so each core has each own potentially different "view" of what the content of the system memory is.

Thread synchronization mechanisms take care of synchronizing between cores, for more information look at http://blogs.msdn.com/oldnewthing/archive/2008/10/03/8969397.aspx or google for acquire and release semantics

Nir
Caches are secondary here. Even if there are no caches and CPUs were talking to memory directly normal read / write sequence is not atomic.
Suma
+3  A: 

Writing a value is never atomic by default. When you write a value to a variable, several machine instructions are generated. With modern, preemptive OSes, the OS might switch to another thread between the individual operations of the write.

This is even more a problem on multi-processor machines, where several threads could be executing at the same time, and trying to write to a single memory location simultaneously.

Interlocked operations avoid this by using specialized instructions to make the write (x86 has dedicated instructions for this kind of situation), which do the read-modify-write in one instruction. These instructions also lock the memory bus of all processors, to ensure that no other executing thread could be writing to the value at the same time.

Mathieu Garstecki