//
int RWLock_AcquireRead(tRWLock *Lock)
{
- tThread *us;
LOG("Acquire RWLock Read %p", Lock);
// Get protector
SHORTLOCK( &Lock->Protector );
// Check if the lock is already held by a writer
- if( Lock->Owner )
+ // - OR, there's a writer waiting to write
+ if( Lock->Owner || Lock->WriterWaiting )
{
LOG("Waiting");
- SHORTLOCK( &glThreadListLock );
-
- // - Remove from active list
- us = Threads_RemActive();
- us->Next = NULL;
- // - Mark as sleeping
- us->Status = THREAD_STAT_RWLOCKSLEEP;
- us->WaitPointer = Lock;
-
- // - Add to waiting
- if(Lock->ReaderWaiting)
- Lock->ReaderWaitingLast->Next = us;
- else
- Lock->ReaderWaiting = us;
- Lock->ReaderWaitingLast = us;
-
- #if DEBUG_TRACE_STATE
- Log("%p (%i %s) waiting on rwlock %p",
- us, us->TID, us->ThreadName, Lock);
- #endif
-
- SHORTREL( &glThreadListLock );
- SHORTREL( &Lock->Protector );
- while(us->Status == THREAD_STAT_RWLOCKSLEEP) Threads_Yield();
- // We're only woken when we get the lock
- // TODO: Handle when this isn't the case
- us->WaitPointer = NULL;
+ Threads_int_Sleep(THREAD_STAT_RWLOCKSLEEP, Lock, 0,
+ &Lock->ReaderWaiting, &Lock->ReaderWaitingLast,
+ &Lock->Protector);
}
// Ooh, no problems then!
else
int RWLock_AcquireWrite(tRWLock *Lock)
{
- tThread *us;
-
LOG("Acquire RWLock Write %p", Lock);
SHORTLOCK(&Lock->Protector);
if( Lock->Owner || Lock->Level != 0 )
{
LOG("Waiting");
- SHORTLOCK(&glThreadListLock);
-
- us = Threads_RemActive();
- us->Next = NULL;
- us->Status = THREAD_STAT_RWLOCKSLEEP;
- us->WaitPointer = Lock;
-
- if( Lock->WriterWaiting )
- Lock->WriterWaitingLast->Next = us;
- else
- Lock->WriterWaiting = us;
- Lock->WriterWaitingLast = us;
-
- SHORTREL( &glThreadListLock );
- SHORTREL( &Lock->Protector );
-
- while(us->Status == THREAD_STAT_RWLOCKSLEEP) Threads_Yield();
- us->WaitPointer = NULL;
+ Threads_int_Sleep(THREAD_STAT_RWLOCKSLEEP, Lock, 0,
+ &Lock->WriterWaiting, &Lock->WriterWaitingLast,
+ &Lock->Protector);
}
else
{