* rwlock.c
* - Reader-Writer Lockes
*/
+#define DEBUG 0
#include <acess.h>
#include <threads_int.h>
#include <rwlock.h>
//
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 )
{
- 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;
+ LOG("Waiting");
+ Threads_int_Sleep(THREAD_STAT_RWLOCKSLEEP, Lock, 0,
+ &Lock->ReaderWaiting, &Lock->ReaderWaitingLast,
+ &Lock->Protector);
}
// Ooh, no problems then!
else
Lock->Level++;
SHORTREL( & Lock->Protector );
}
+ LOG("Obtained");
return 0;
}
int RWLock_AcquireWrite(tRWLock *Lock)
{
- tThread *us;
+ LOG("Acquire RWLock Write %p", Lock);
SHORTLOCK(&Lock->Protector);
if( Lock->Owner || Lock->Level != 0 )
{
- 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;
+ LOG("Waiting");
+ Threads_int_Sleep(THREAD_STAT_RWLOCKSLEEP, Lock, 0,
+ &Lock->WriterWaiting, &Lock->WriterWaitingLast,
+ &Lock->Protector);
}
else
{
Lock->Owner = Proc_GetCurThread();
SHORTREL(&Lock->Protector);
}
+ LOG("Obtained");
return 0;
}
// Release a mutex
void RWLock_Release(tRWLock *Lock)
{
+ LOG("Release RWLock %p", Lock);
SHORTLOCK( &Lock->Protector );
- if( Lock->Owner == Proc_GetCurThread() )
+ if( Lock->Owner != Proc_GetCurThread() )
Lock->Level --;
// Writers first