Click here to Skip to main content
15,896,727 members
Articles / Desktop Programming / Win32

Spin Lock in C++

Rate me:
Please Sign up or sign in to vote.
4.85/5 (21 votes)
9 May 2011CPOL7 min read 129.8K   2K   50  
A spin lock implementation which can be used for general purpose locking.
#include "SpinLock.h"
#include <iostream>

using namespace LockFree;
using namespace std;

void tSpinWait::Lock(tSpinLock &LockObj)
{
	m_iterations = 0;
	while(true)
	{
		// A thread alreading owning the lock shouldn't be allowed to wait to acquire the lock - reentrant safe
		if(LockObj.dest == GetCurrentThreadId())
			break;
		/*
		  Spinning in a loop of interlockedxxx calls can reduce the available memory bandwidth and slow
		  down the rest of the system. Interlocked calls are expensive in their use of the system memory
		  bus. It is better to see if the 'dest' value is what it is expected and then retry interlockedxx.
		*/
		if(InterlockedCompareExchange(&LockObj.dest, LockObj.exchange, LockObj.compare) == 0)
		{
			//assign CurrentThreadId to dest to make it re-entrant safe
			LockObj.dest = GetCurrentThreadId();
			// lock acquired 
			break;			
		}
			
		// spin wait to acquire 
		while(LockObj.dest != LockObj.compare)
		{
			if(HasThreasholdReached())
			{
				if(m_iterations + YIELD_ITERATION >= MAX_SLEEP_ITERATION)
					Sleep(0);
				
				if(m_iterations >= YIELD_ITERATION && m_iterations < MAX_SLEEP_ITERATION)
				{
					m_iterations = 0;
					SwitchToThread();
				}
			}
			// Yield processor on multi-processor but if on single processor then give other thread the CPU
			m_iterations++;
			if(Helper::GetNumberOfProcessors() > 1) { YieldProcessor(/*no op*/); }
			else { SwitchToThread(); }				
		}				
	}
}
//

void tSpinWait::Unlock(tSpinLock &LockObj)
{
	if(LockObj.dest != GetCurrentThreadId())
		throw std::runtime_error("Unexpected thread-id in release");
	// lock released
	InterlockedCompareExchange(&LockObj.dest, LockObj.compare, GetCurrentThreadId());	
}
//

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead Thomson Reuters Ltd, London
United Kingdom United Kingdom
Studied MSc Network and Parallel computing from Reading University, UK. I was always interested in IT. Previously worked in Network-Security, Games Development, Satellite Communications and now in Financial Services industry. After work, usually time spent with my son. Love playing cricket, badminton - though not happening much on sports these days. OK, enough about me.

Email: sameer_87@hotmail.com

Comments and Discussions