From 6b29d7427e7d1ad73f0a0d0ae771bd25da7b7f1a Mon Sep 17 00:00:00 2001 From: "John Hodge (sonata)" Date: Fri, 1 Feb 2013 10:45:37 +0800 Subject: [PATCH] Kernel - Removed while() loops in locks with Threads_int_WaitForStatusEnd - Should allow userland usage of lock code --- KernelLand/Kernel/include/threads_int.h | 2 ++ KernelLand/Kernel/mutex.c | 2 +- KernelLand/Kernel/rwlock.c | 4 ++-- KernelLand/Kernel/semaphore.c | 12 +++--------- KernelLand/Kernel/threads.c | 23 +++++++++++++++++------ 5 files changed, 25 insertions(+), 18 deletions(-) diff --git a/KernelLand/Kernel/include/threads_int.h b/KernelLand/Kernel/include/threads_int.h index 642f6c32..09e58c16 100644 --- a/KernelLand/Kernel/include/threads_int.h +++ b/KernelLand/Kernel/include/threads_int.h @@ -125,6 +125,7 @@ static const char * const casTHREAD_STAT[] = { "THREAD_STAT_ACTIVE", "THREAD_STAT_SLEEPING", "THREAD_STAT_MUTEXSLEEP", + "THREAD_STAT_RWLOCKSLEEP", "THREAD_STAT_SEMAPHORESLEEP", "THREAD_STAT_QUEUESLEEP", "THREAD_STAT_EVENTSLEEP", @@ -152,6 +153,7 @@ extern tThread *Threads_GetNextToRun(int CPU, tThread *Last); extern tThread *Threads_CloneTCB(Uint Flags); extern tThread *Threads_CloneThreadZero(void); +extern void Threads_int_WaitForStatusEnd(enum eThreadStatus Status); extern void Semaphore_ForceWake(tThread *Thread); #endif diff --git a/KernelLand/Kernel/mutex.c b/KernelLand/Kernel/mutex.c index 597242b6..d74cde8f 100644 --- a/KernelLand/Kernel/mutex.c +++ b/KernelLand/Kernel/mutex.c @@ -66,7 +66,7 @@ int Mutex_Acquire(tMutex *Mutex) SHORTREL( &glThreadListLock ); SHORTREL( &Mutex->Protector ); - while(us->Status == THREAD_STAT_MUTEXSLEEP) Threads_Yield(); + Threads_int_WaitForStatusEnd(THREAD_STAT_MUTEXSLEEP); // We're only woken when we get the lock us->WaitPointer = NULL; } diff --git a/KernelLand/Kernel/rwlock.c b/KernelLand/Kernel/rwlock.c index 979df4ac..a6aeca88 100644 --- a/KernelLand/Kernel/rwlock.c +++ b/KernelLand/Kernel/rwlock.c @@ -48,7 +48,7 @@ int RWLock_AcquireRead(tRWLock *Lock) SHORTREL( &glThreadListLock ); SHORTREL( &Lock->Protector ); - while(us->Status == THREAD_STAT_RWLOCKSLEEP) Threads_Yield(); + 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; @@ -90,7 +90,7 @@ int RWLock_AcquireWrite(tRWLock *Lock) SHORTREL( &glThreadListLock ); SHORTREL( &Lock->Protector ); - while(us->Status == THREAD_STAT_RWLOCKSLEEP) Threads_Yield(); + Threads_int_WaitForStatusEnd(THREAD_STAT_RWLOCKSLEEP); us->WaitPointer = NULL; } else diff --git a/KernelLand/Kernel/semaphore.c b/KernelLand/Kernel/semaphore.c index ce7d4ba0..24174735 100644 --- a/KernelLand/Kernel/semaphore.c +++ b/KernelLand/Kernel/semaphore.c @@ -79,17 +79,11 @@ int Semaphore_Wait(tSemaphore *Sem, int MaxToTake) SHORTREL( &Sem->Protector ); // Release first to make sure it is released SHORTREL( &glThreadListLock ); // Sleep until woken (either by getting what we need, or a timer event) - while( us->Status == THREAD_STAT_SEMAPHORESLEEP ) - { - Threads_Yield(); - if(us->Status == THREAD_STAT_SEMAPHORESLEEP) - Log_Warning("Threads", "Semaphore %p %s:%s re-schedulued while asleep", - Sem, Sem->ModName, Sem->Name); - } + 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", Sem, Sem->ModName, Sem->Name); #endif - // We're only woken when there's something avaliable (or a signal arrives) us->WaitPointer = NULL; taken = us->RetStatus; @@ -191,7 +185,7 @@ int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd) SHORTREL( &glThreadListLock ); SHORTREL( &Sem->Protector ); - while(us->Status == THREAD_STAT_SEMAPHORESLEEP) Threads_Yield(); + Threads_int_WaitForStatusEnd(THREAD_STAT_SEMAPHORESLEEP); // We're only woken when there's something avaliable us->WaitPointer = NULL; diff --git a/KernelLand/Kernel/threads.c b/KernelLand/Kernel/threads.c index a86eba07..7dd9f6e9 100644 --- a/KernelLand/Kernel/threads.c +++ b/KernelLand/Kernel/threads.c @@ -712,6 +712,22 @@ void Threads_Yield(void) Proc_Reschedule(); } +/** + * \breif Wait for the thread status to not be a specified value + */ +void Threads_int_WaitForStatusEnd(enum eThreadStatus Status) +{ + tThread *us = Proc_GetCurThread(); + ASSERT(Status != THREAD_STAT_ACTIVE); + ASSERT(Status != THREAD_STAT_DEAD); + while( us->Status == Status ) + { + Proc_Reschedule(); + if( us->Status == Status ) + Debug("Thread %p(%i %s) rescheduled while in %s state", casTHREAD_STAT[Status]); + } +} + /** * \fn void Threads_Sleep(void) * \brief Take the current process off the run queue @@ -743,12 +759,7 @@ void Threads_Sleep(void) // Release Spinlock SHORTREL( &glThreadListLock ); - - while(cur->Status != THREAD_STAT_ACTIVE) { - Proc_Reschedule(); - if( cur->Status != THREAD_STAT_ACTIVE ) - Log("%i - Huh? why am I up? zzzz...", cur->TID); - } + Threads_int_WaitForStatusEnd(THREAD_STAT_SLEEPING); } -- 2.20.1