X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Frwlock.c;h=1fd64592325ee191dd2f54eb69a1ba792d121306;hb=13078002b01ee4f63eb2001d2ef479a2a006ea32;hp=6706bb228f66f1ce03940c621b0ed3fd72d67c71;hpb=be490e1dd003780a02493a51ebbab1a5225c30d1;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/rwlock.c b/KernelLand/Kernel/rwlock.c index 6706bb22..1fd64592 100644 --- a/KernelLand/Kernel/rwlock.c +++ b/KernelLand/Kernel/rwlock.c @@ -5,6 +5,7 @@ * rwlock.c * - Reader-Writer Lockes */ +#define DEBUG 0 #include #include #include @@ -15,40 +16,18 @@ // 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 ) { - 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 @@ -56,35 +35,22 @@ int RWLock_AcquireRead(tRWLock *Lock) 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 { @@ -92,15 +58,17 @@ int RWLock_AcquireWrite(tRWLock *Lock) 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