Skip to content

Instantly share code, notes, and snippets.

@baiyanhuang
Created July 1, 2012 09:31
Show Gist options
  • Save baiyanhuang/3027686 to your computer and use it in GitHub Desktop.
Save baiyanhuang/3027686 to your computer and use it in GitHub Desktop.
Spin lock implementation in Windows and depends on it a double-checked singleton.
// we use double-lock check in singleton to solve the problem we met in spinlock1.cpp, but hey, that itself is a lock, it has to use some atomic intrusion/memory barrier to solve this synchronization problem
template<class T>
class SingletonHolder
{
private:
static volatile T* instance;
static volatile int m_lockObj;
SingletonHolder() {}
public:
static T* get()
{
if(instance == NULL)
{
// TODO: use RAII to make it exception safe.
Lock lock;
lock.lock(m_lockObj);
if(instance == NULL)
instance = new T();
lock.unlock(m_lockObj);
}
return instance;
}
}
template<class T> SingletonHolder::instance = NULL;
template<class T> SingletonHolder::m_lockObj = 0;
// The right way
class Lock
{
void lock(volatile int* lockObj)
{
while(true)
{
// CAS: compare and swap
// synchronized: if(*lockObj == 0) *lockObj = 1;
if(interlockedCompareExchange(lockObj, 1, 0) == 0)
{
// lock acquired
break;
}
}
}
// release the lock
void unlock(volatile int* lockObj)
{
// lock released
*lockObj = 0;
}
};
// The wrong way - the check and assignment is not atomic, there is a race condition there.
class Lock
{
void lock(volatile int* lockObj)
{
while(true)
{
if(*lockObj == 0)
{
*lockObj = 1;
break;
}
}
}
// release the lock
void unlock(volatile int* lockObj)
{
// lock released
*lockObj= 0;
}
};
@baiyanhuang
Copy link
Author

production-level的spinlock windows实现见此:http://www.codeproject.com/Articles/184046/Spin-Lock-in-C

@baiyanhuang
Copy link
Author

volatile在C++标准中的定义保证一个线程的修改,在另外一个线程中是可见的。
但在windows下,微软做了更多:保证volatile的读写不会被乱序优化 (编译时): http://msdn.microsoft.com/en-us/library/12a04hfd(v=vs.80).aspx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment