Kernel - Removed while() loops in locks with Threads_int_WaitForStatusEnd
authorJohn Hodge (sonata) <[email protected]>
Fri, 1 Feb 2013 02:45:37 +0000 (10:45 +0800)
committerJohn Hodge (sonata) <[email protected]>
Fri, 1 Feb 2013 02:45:37 +0000 (10:45 +0800)
- Should allow userland usage of lock code

KernelLand/Kernel/include/threads_int.h
KernelLand/Kernel/mutex.c
KernelLand/Kernel/rwlock.c
KernelLand/Kernel/semaphore.c
KernelLand/Kernel/threads.c

index 642f6c3..09e58c1 100644 (file)
@@ -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
index 597242b..d74cde8 100644 (file)
@@ -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;
        }
index 979df4a..a6aeca8 100644 (file)
@@ -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
index ce7d4ba..2417473 100644 (file)
@@ -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;
                
index a86eba0..7dd9f6e 100644 (file)
@@ -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);
 }
 
 

UCC git Repository :: git.ucc.asn.au