Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I atomically swap two pointers on Windows?

Tags:

c++

windows

Okay, I'm asking the same thing as this deleted question, but I'm asking it more directly.

I've got two pointer variables in two instances of the same class. I'd like to swap the contents of those variables (not what they POINT to, just the variables themselves) atomically.

I'd like to avoid locks if at all possible.

How do I do this?

EDIT: To the three zillion "InterlockedExchangePointer" answers, please read the MSDN docs first. InterlockedExchangePointer exchanges the value of a pointer target with a value on the stack register. It (by itself) does not exchange two pointers in memory locations.

like image 243
Billy ONeal Avatar asked Dec 21 '10 20:12

Billy ONeal


2 Answers

I'm going to go out on a limb and say that you need a lock and that there is no general-case lock-free solution to this problem.

You would need to read from two addresses and write back to both addresses all atomically. To the best of my knowledge, X86 can only atomically exchange data from a single memory address and a register. I don't think it's possible to exchange the contents of two memory addresses.

If you can put constraints on where the pointers are, you can do this. For example, if you can guarantee the pointers are adjacent in memory, you can use a 64- or 128-bit compare/exchange in a loop.

There may be solutions for other simple cases, but I don't think you're going to find a lock-free solution for the general case.

like image 108
James McNellis Avatar answered Sep 19 '22 14:09

James McNellis


You are looking for an atomic, interlocked version of swap.

To my knowledge, there is no way to do this using only Windows API primitives and no explicit locking. The various Interlocked functions being recommended by others will not work because only one of the passed-parameters is changed. You want to change them both.

I might also point out that the Interlocked functions are only interlocked with respect to each other. If you have another piece of code that updates one of these pointers but doesn't use Interlocked, your code is no longer safe. I'm sure you realize this, but thought I'd mention it.

As far as I know, you'll need to use a library or write your own code to handle this.

like image 39
John Dibling Avatar answered Sep 18 '22 14:09

John Dibling