From: John Hodge Date: Sun, 3 Nov 2013 12:43:35 +0000 (+0800) Subject: Kernel - Converted most blocking states to use Threads_int_Sleep X-Git-Tag: rel0.15~101 X-Git-Url: https://git.ucc.asn.au/?p=tpg%2Facess2.git;a=commitdiff_plain;h=d3c92d9489a096db306e5a028ad65ff95431ba7d Kernel - Converted most blocking states to use Threads_int_Sleep --- diff --git a/KernelLand/Kernel/include/threads_int.h b/KernelLand/Kernel/include/threads_int.h index 4b4641ce..403a2eff 100644 --- a/KernelLand/Kernel/include/threads_int.h +++ b/KernelLand/Kernel/include/threads_int.h @@ -161,6 +161,7 @@ extern tThread *Threads_GetNextToRun(int CPU, tThread *Last); extern tThread *Threads_CloneTCB(Uint Flags); extern tThread *Threads_CloneThreadZero(void); +extern int Threads_int_Sleep(enum eThreadStatus Status, void *Ptr, int Num, tThread **ListHead, tThread **ListTail, tShortSpinlock *Lock); extern void Threads_int_WaitForStatusEnd(enum eThreadStatus Status); extern void Semaphore_ForceWake(tThread *Thread); diff --git a/KernelLand/Kernel/mutex.c b/KernelLand/Kernel/mutex.c index d74cde8f..a869df53 100644 --- a/KernelLand/Kernel/mutex.c +++ b/KernelLand/Kernel/mutex.c @@ -31,47 +31,14 @@ int Mutex_Acquire(tMutex *Mutex) // Check if the lock is already held if( Mutex->Owner ) { - SHORTLOCK( &glThreadListLock ); - // - Remove from active list - us = Threads_RemActive(); - us->Next = NULL; - // - Mark as sleeping - us->Status = THREAD_STAT_MUTEXSLEEP; - us->WaitPointer = Mutex; - - // - Add to waiting - if(Mutex->LastWaiting) { - Mutex->LastWaiting->Next = us; - Mutex->LastWaiting = us; - } - else { - Mutex->Waiting = us; - Mutex->LastWaiting = us; - } - - #if DEBUG_TRACE_STATE - Log("%p (%i %s) waiting on mutex %p", - us, us->TID, us->ThreadName, Mutex); - #endif - - #if 0 - { - int i = 0; - tThread *t; - for( t = Mutex->Waiting; t; t = t->Next, i++ ) - Log("[%i] (tMutex)%p->Waiting[%i] = %p (%i %s)", us->TID, Mutex, i, - t, t->TID, t->ThreadName); - } - #endif - - SHORTREL( &glThreadListLock ); - SHORTREL( &Mutex->Protector ); - Threads_int_WaitForStatusEnd(THREAD_STAT_MUTEXSLEEP); - // We're only woken when we get the lock - us->WaitPointer = NULL; + // Sleep on the lock + Threads_int_Sleep(THREAD_STAT_MUTEXSLEEP, + Mutex, 0, + &Mutex->Waiting, &Mutex->LastWaiting, &Mutex->Protector); + // - We're only woken when we get the lock } - // Ooh, let's take it! else { + // If not, just obtain it Mutex->Owner = us; SHORTREL( &Mutex->Protector ); } diff --git a/KernelLand/Kernel/rwlock.c b/KernelLand/Kernel/rwlock.c index a6aeca88..c39ce10a 100644 --- a/KernelLand/Kernel/rwlock.c +++ b/KernelLand/Kernel/rwlock.c @@ -16,7 +16,6 @@ // int RWLock_AcquireRead(tRWLock *Lock) { - tThread *us; LOG("Acquire RWLock Read %p", Lock); // Get protector SHORTLOCK( &Lock->Protector ); @@ -25,33 +24,9 @@ int RWLock_AcquireRead(tRWLock *Lock) if( Lock->Owner ) { 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 ); - Threads_int_WaitForStatusEnd(THREAD_STAT_RWLOCKSLEEP); - // 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 @@ -66,32 +41,15 @@ int RWLock_AcquireRead(tRWLock *Lock) 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 ); - - Threads_int_WaitForStatusEnd(THREAD_STAT_RWLOCKSLEEP); - us->WaitPointer = NULL; + Threads_int_Sleep(THREAD_STAT_RWLOCKSLEEP, Lock, 0, + &Lock->WriterWaiting, &Lock->WriterWaitingLast, + &Lock->Protector); } else { diff --git a/KernelLand/Kernel/semaphore.c b/KernelLand/Kernel/semaphore.c index e8175741..0b70df5e 100644 --- a/KernelLand/Kernel/semaphore.c +++ b/KernelLand/Kernel/semaphore.c @@ -28,7 +28,6 @@ void Semaphore_Init(tSemaphore *Sem, int Value, int MaxValue, const char *Module // int Semaphore_Wait(tSemaphore *Sem, int MaxToTake) { - tThread *us; int taken; if( MaxToTake < 0 ) { Log_Warning("Threads", "Semaphore_Wait: User bug - MaxToTake(%i) < 0, Sem=%p(%s)", @@ -50,48 +49,9 @@ int Semaphore_Wait(tSemaphore *Sem, int MaxToTake) } else { - #if 0 - Threads_int_Sleep(THREAD_STAT_SEMAPHORESLEEP, + taken = Threads_int_Sleep(THREAD_STAT_SEMAPHORESLEEP, Sem, MaxToTake, &Sem->Waiting, &Sem->LastWaiting, &Sem->Protector); - #endif - SHORTLOCK( &glThreadListLock ); - - // - Remove from active list - us = Threads_RemActive(); - us->Next = NULL; - // - Mark as sleeping - us->Status = THREAD_STAT_SEMAPHORESLEEP; - us->WaitPointer = Sem; - us->RetStatus = MaxToTake; // Use RetStatus as a temp variable - - // - Add to waiting - if(Sem->LastWaiting) { - Sem->LastWaiting->Next = us; - Sem->LastWaiting = us; - } - else { - Sem->Waiting = us; - Sem->LastWaiting = us; - } - - #if DEBUG_TRACE_STATE || SEMAPHORE_DEBUG - Log("%p (%i %s) waiting on semaphore %p %s:%s", - us, us->TID, us->ThreadName, - Sem, Sem->ModName, Sem->Name); - #endif - SHORTREL( &Sem->Protector ); - SHORTREL( &glThreadListLock ); - // NOTE: This can break in SMP - // Sleep until woken (either by getting what we need, or a timer event) - Threads_int_WaitForStatusEnd( THREAD_STAT_SEMAPHORESLEEP ); - // We're only woken when there's something avaliable (or a signal arrives) - #if DEBUG_TRACE_STATE || SEMAPHORE_DEBUG - Log("Semaphore %p %s:%s woken from wait", Sem, Sem->ModName, Sem->Name); - #endif - us->WaitPointer = NULL; - - taken = us->RetStatus; // Get the lock again SHORTLOCK( &Sem->Protector ); @@ -157,44 +117,13 @@ int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd) // Check if we have to block if( Sem->MaxValue && Sem->Value == Sem->MaxValue ) { - tThread *us; #if 0 Log_Debug("Threads", "Semaphore_Signal: IDLE Sem = %s:%s", Sem->ModName, Sem->Name); Log_Debug("Threads", "Semaphore_Signal: Sem->Value(%i) == Sem->MaxValue(%i)", Sem->Value, Sem->MaxValue); #endif - - SHORTLOCK( &glThreadListLock ); - // - Remove from active list - us = Threads_RemActive(); - us->Next = NULL; - // - Mark as sleeping - us->Status = THREAD_STAT_SEMAPHORESLEEP; - us->WaitPointer = Sem; - us->RetStatus = AmmountToAdd; // Use RetStatus as a temp variable - - // - Add to waiting - if(Sem->LastSignaling) { - Sem->LastSignaling->Next = us; - Sem->LastSignaling = us; - } - else { - Sem->Signaling = us; - Sem->LastSignaling = us; - } - - #if DEBUG_TRACE_STATE || SEMAPHORE_DEBUG - Log("%p (%i %s) signaling semaphore %p %s:%s", - us, us->TID, us->ThreadName, - Sem, Sem->ModName, Sem->Name); - #endif - - SHORTREL( &glThreadListLock ); - SHORTREL( &Sem->Protector ); - Threads_int_WaitForStatusEnd(THREAD_STAT_SEMAPHORESLEEP); - // We're only woken when there's something avaliable - us->WaitPointer = NULL; - - added = us->RetStatus; + added = Threads_int_Sleep(THREAD_STAT_SEMAPHORESLEEP, + Sem, AmmountToAdd, + &Sem->Signaling, &Sem->LastSignaling, &Sem->Protector); // Get the lock again SHORTLOCK( &Sem->Protector ); diff --git a/KernelLand/Kernel/threads.c b/KernelLand/Kernel/threads.c index 21dc055f..a1d3cdb9 100644 --- a/KernelLand/Kernel/threads.c +++ b/KernelLand/Kernel/threads.c @@ -60,7 +60,7 @@ void Threads_Exit(int TID, int Status); void Threads_Kill(tThread *Thread, int Status); void Threads_Yield(void); #endif -void Threads_int_Sleep(enum eThreadStatus Status, void *Ptr, int Num, tThread **ListHead, tThread **ListTail, tShortSpinlock *Lock); + int Threads_int_Sleep(enum eThreadStatus Status, void *Ptr, int Num, tThread **ListHead, tThread **ListTail, tShortSpinlock *Lock); #if 0 void Threads_Sleep(void); int Threads_Wake(tThread *Thread); @@ -754,7 +754,7 @@ void Threads_int_WaitForStatusEnd(enum eThreadStatus Status) } } -void Threads_int_Sleep(enum eThreadStatus Status, void *Ptr, int Num, tThread **ListHead, tThread **ListTail, tShortSpinlock *Lock) +int Threads_int_Sleep(enum eThreadStatus Status, void *Ptr, int Num, tThread **ListHead, tThread **ListTail, tShortSpinlock *Lock) { SHORTLOCK( &glThreadListLock ); tThread *us = Threads_RemActive(); @@ -768,12 +768,11 @@ void Threads_int_Sleep(enum eThreadStatus Status, void *Ptr, int Num, tThread ** if( ListTail ) { if(*ListTail) { (*ListTail)->Next = us; - *ListTail = us; } else { *ListHead = us; - *ListTail = us; } + *ListTail = us; } else { *ListHead = us; @@ -783,8 +782,10 @@ void Threads_int_Sleep(enum eThreadStatus Status, void *Ptr, int Num, tThread ** // return ; SHORTREL( &glThreadListLock ); if( Lock ) - SHORTLOCK( Lock ); + SHORTREL( Lock ); Threads_int_WaitForStatusEnd(Status); + us->WaitPointer = NULL; + return us->RetStatus; } /** diff --git a/KernelLand/Kernel/workqueue.c b/KernelLand/Kernel/workqueue.c index 2083bde7..3e35b069 100644 --- a/KernelLand/Kernel/workqueue.c +++ b/KernelLand/Kernel/workqueue.c @@ -20,8 +20,6 @@ void Workqueue_Init(tWorkqueue *Queue, const char *Name, size_t NextOfset) void *Workqueue_GetWork(tWorkqueue *Queue) { - tThread *us; - for( ;; ) { // Check for work @@ -36,25 +34,9 @@ void *Workqueue_GetWork(tWorkqueue *Queue) return ret; } - #if 0 Threads_int_Sleep(THREAD_STAT_QUEUESLEEP, Queue, 0, &Queue->Sleeper, NULL, &Queue->Protector); - #endif - // Go to sleep - SHORTLOCK(&glThreadListLock); - us = Threads_RemActive(); - us->WaitPointer = Queue; - us->Status = THREAD_STAT_QUEUESLEEP; - Queue->Sleeper = us; - - SHORTREL(&Queue->Protector); - SHORTREL(&glThreadListLock); - - // Yield and sleep - Threads_int_WaitForStatusEnd(THREAD_STAT_QUEUESLEEP); - - us->WaitPointer = NULL; } }