I would appreciate an advice in creating my own interlocked operation for 64-bit values.
I do a busy waiting using the standard Interlocked operations.
enum
{
LOCK_TAKEN = 0x51ab3456,
LOCK_FREE = 0x4d3e76bb
};
#define SA_UTILS_INTERLOCKED_CS_ENTER(pLock) \
{ \
while (InterlockedCompareExchange((pLock), LOCK_TAKEN, LOCK_FREE) != LOCK_FREE); \
}
#define SA_UTILS_INTERLOCKED_CS_EXIT(pLock) \
{ \
LONG prevLockValue = InterlockedCompareExchange((pLock), LOCK_FREE, LOCK_TAKEN); \
\
SAUTILS_ASSERT(prevLockValue == LOCK_TAKEN); \
}
VOID SaUtilsInitInterlocked64Lock(PLONG pLock)
{
*pLock = LOCK_FREE;
}
UINT64 SaUtilsInterlockedExchangeAdd64(PUINT64 pTarget, UINT64 value, PLONG pLock)
{
UINT64 result = 0;
SA_UTILS_INTERLOCKED_CS_ENTER(pLock);
result = *pTarget;
*pTarget += value;
SA_UTILS_INTERLOCKED_CS_EXIT(pLock);
return result;
}
UINT64 SaUtilsInterlockedGet64(PUINT64 pTarget, PLONG pLock)
{
UINT64 result = 0;
SA_UTILS_INTERLOCKED_CS_ENTER(pLock);
result = *pTarget;
SA_UTILS_INTERLOCKED_CS_EXIT(pLock);
return result;
}
UINT64 SaUtilsInterlockedExchange64(PUINT64 pTarget, UINT64 value, PLONG pLock)
{
UINT64 prevValue = 0;
SA_UTILS_INTERLOCKED_CS_ENTER(pLock);
prevValue = *pTarget;
*pTarget = value;
SA_UTILS_INTERLOCKED_CS_EXIT(pLock);
return prevValue;
}
However,
from time to time I receive a deadlock in SaUtilsInterlockedExchangeAdd64.
I never get out of the while loop and the value of the lock is LOCK_TAKEN.
It’s like somebody has never set the lock to LOCK_FREE.
It’s not clear how this can happen.
I would appreciate your advice.
Thanks,
Alex.