Search code examples
c++multithreadingatomic

InterlockedExchange vs InterlockedCompareExchange spin locks


I've written a basic spin lock (see below) using InterlockedExchange. However I've seen a lot of implementations use InterlockedCompareExchange instead. Is mine incorrect in some unforeseen way and if not what are the pro's and cons of each way (if indeed there are any)?

PS I know the sleep is expensive and I'd want to have an attempt count before I call it.

class SpinLock
{
public:

    SpinLock() : m_lock( 0 ) {}
    ~SpinLock(){}

    void Lock()
    {
        while( InterlockedExchange( &m_lock, 1 ) == 1 )
        { 
            Sleep( 0 ); 
        }
    }

    void Unlock()
    {
        InterlockedExchange( &m_lock, 0 );
    }

private:
    volatile unsigned int m_lock;
};

Solution

  • There is very little difference between CMPXCHG and XCHG (which is the x86 instructions that you'd get from the two intrinsic functions you mention).

    I think the main difference is that in a SMP system with a lot of contention on the lock, you don't get a bunch of writes when the value is already "locked" - which means that the other processors don't have to read back a value that is already there in the cache.

    In a debug build, you'd also want to ensure that Unlock() is only called from the current owner of the lock!