#include "progwrp.h" #include "export.h" #include "implementations.h" #include typedef struct { ULONG_PTR pSRWLock; HANDLE hEvent; } WAITER, * PWAITER; WAITER ExclusiveWaiters[512]; WAITER SharedWaiters[512]; typedef struct { USHORT Readers; USHORT WaitingWriters; }SRWLOCK_INT, * PSRWLOCK_INT; BOOLEAN WINAPI Implementation_TryAcquireSRWLockExclusive(PSRWLOCK_INT SRWLock) { // printf("Attempting to acquire SRW Lock holding:\n Exclusive Lock: %d\n Readers: %d\n Waiting Writers: %d\n", SRWLock->WaitingWriters & (1 << 15), SRWLock->Readers, SRWLock->WaitingWriters); // printf("Trying to acquire exclusive SRW lock, value 0x%X at 0x%X, TID %d\n", SRWLock->Ptr, SRWLock, GetCurrentThreadId()); return !_interlockedbittestandset(SRWLock, 31); } BOOLEAN WINAPI Implementation_TryAcquireSRWLockShared(PSRWLOCK_INT SRWLock) { // printf("Attempting to acquire SRW Lock holding:\n Exclusive Lock: %d\n Readers: %d\n Waiting Writers: %d\n", SRWLock->WaitingWriters & (1 << 15), SRWLock->Readers, SRWLock->WaitingWriters); // printf("Trying to acquire shared SRW lock, value 0x%X at 0x%X, TID %d\n", SRWLock->Ptr, SRWLock, GetCurrentThreadId()); if (!SRWLock->WaitingWriters) { if (!_interlockedbittestandset(SRWLock, 31)) { InterlockedIncrement16(&SRWLock->Readers); return TRUE; } } if (SRWLock->WaitingWriters && SRWLock->Readers) { InterlockedIncrement16(&SRWLock->Readers); return TRUE; } return FALSE; //return !_interlockedbittestandset(SRWLock, 0); } void WINAPI Implementation_AcquireSRWLockExclusive(PSRWLOCK_INT SRWLock) { // printf("Attempting to acquire SRW Lock holding:\n Exclusive Lock: %d\n Readers: %d\n Waiting Writers: %d\n", SRWLock->WaitingWriters & (1 << 15), SRWLock->Readers, SRWLock->WaitingWriters); if (_interlockedbittestandset(SRWLock, 31)) { // EnterCriticalSection(&SrwSharedCs2); InterlockedIncrement16(&SRWLock->WaitingWriters); // _interlockedbittestandset(SRWLock, 31); // LeaveCriticalSection(&SrwSharedCs2); wait: //WaitForSingleObject(g_SRWEvent, INFINITE); Sleep(1); if (!_interlockedbittestandset(SRWLock, 31)) { // EnterCriticalSection(&SrwSharedCs2); InterlockedDecrement16(&SRWLock->WaitingWriters); // LeaveCriticalSection(&SrwSharedCs2); return; } else { goto wait; } } } void WINAPI Implementation_AcquireSRWLockShared(PSRWLOCK_INT SRWLock) { // printf("Attempting to acquire SRW Lock holding:\n Exclusive Lock: %d\n Readers: %d\n Waiting Writers: %d\n", SRWLock->WaitingWriters & (1 << 15), SRWLock->Readers, SRWLock->WaitingWriters); if (_interlockedbittestandset(SRWLock, 31)) { if (SRWLock->Readers) { InterlockedIncrement16(&SRWLock->Readers); return; } // InterlockedIncrement16(&SRWLock->WaitingReaders); wait: //WaitForSingleObject(g_SRWEvent, INFINITE); Sleep(1); if (!SRWLock->WaitingWriters) { _interlockedbittestandset(SRWLock, 31); // InterlockedDecrement16(&SRWLock->WaitingReaders); InterlockedIncrement16(&SRWLock->Readers); return; } else if (SRWLock->Readers) { // InterlockedDecrement16(&SRWLock->WaitingReaders); InterlockedIncrement16(&SRWLock->Readers); return; } else goto wait; } else { InterlockedIncrement16(&SRWLock->Readers); } } void WINAPI Implementation_ReleaseSRWLockShared(PSRWLOCK_INT SRWLock) { // printf("Release attempt made on SRW Lock holding:\n Exclusive Lock: %d\n Readers: %d\n Waiting Writers: %d\n", SRWLock->WaitingWriters & (1 << 15), SRWLock->Readers, SRWLock->WaitingWriters); if (!InterlockedDecrement16(&SRWLock->Readers)) _interlockedbittestandreset(SRWLock, 31); //SetEvent(g_SRWEvent); // ResetEvent(g_SRWEvent); } void WINAPI Implementation_ReleaseSRWLockExclusive(PSRWLOCK_INT SRWLock) { // printf("Release attempt made on SRW Lock holding:\n Exclusive Lock: %d\n Readers: %d\n Waiting Writers: %d\n", SRWLock->WaitingWriters & (1 << 15), SRWLock->Readers, SRWLock->WaitingWriters); _interlockedbittestandreset(SRWLock, 31); // SetEvent(g_SRWEvent); // ResetEvent(g_SRWEvent); } BOOLEAN WINAPI Implementation_TryAcquireSRWLockExclusive_Vista(PSRWLOCK SRWLock) { return !_interlockedbittestandset(SRWLock, 0); } BOOLEAN WINAPI Implementation_TryAcquireSRWLockShared_Vista(PSRWLOCK SRWLock) { ULONG_PTR InterlockedVal; ULONG_PTR NewSRWValue = 0x11; ULONG_PTR OldSRWValue = 1; InterlockedVal = (ULONG_PTR)InterlockedCompareExchange(SRWLock, 0x11, 0); if (InterlockedVal) { if (InterlockedVal == 1) return FALSE; else { while (InterlockedVal) { InterlockedVal = InterlockedCompareExchange(SRWLock, NewSRWValue, OldSRWValue); if (InterlockedVal == OldSRWValue) return TRUE; if (InterlockedVal == 1 || InterlockedVal % 0x10 != 1) return FALSE; NewSRWValue += 0x10; OldSRWValue += 0x10; } } } return TRUE; } void WINAPI Implementation_InitializeSRWLock( PSRWLOCK SRWLock ) { SRWLock->Ptr = 0; }