I want to implement a simple multi-reader/single-writer lock using a volatile value.
Although _InterlockedXXX provides full fence barrier and, if i'm right, also "volatile" keyword, I want to know about possible defects and improvements. I have no experience with acquire/release semantics.
My code:
BOOL TryAcquireShared(LONG volatile *lpnValue)
{
LONG initVal;
do
{
initVal = *lpnValue;
if (initVal == 0x80000000L)
return FALSE; //a writer is active
}
while (_InterlockedCompareExchange(lpnValue, initVal+1, initVal) != initVal);
return TRUE;
}
VOID ReleaseShared(LONG volatile *lpnValue)
{
LONG initVal, newVal;
do
{
initVal = *lpnValue;
newVal = (initVal & 0x80000000L) | ((initVal & 0x7FFFFFFFL) - 1);
}
while (_InterlockedCompareExchange(lpnValue, newVal, initVal) != initVal);
return;
}
BOOL TryAcquireExclusive(LONG volatile *lpnValue)
{
LONG i, initVal, newVal;
do
{
initVal = *lpnValue;
if ((initVal & 0x80000000L) != 0)
return FALSE; //another writer is active or waiting
}
while (_InterlockedCompareExchange(lpnValue, initVal | 0x80000000L, initVal) != initVal);
//wait until no readers
while ((*lpnValue & 0x7FFFFFFFL) != 0)
::Sleep(1);
return TRUE;
}
VOID ReleaseExclusive(LONG volatile *lpnValue)
{
_InterlockedExchange(lpnValue, 0);
return;
}
Also, if you know a library that can handle this, please tell me.