Kernel - Converted most blocking states to use Threads_int_Sleep
authorJohn Hodge <[email protected]>
Sun, 3 Nov 2013 12:43:35 +0000 (20:43 +0800)
committerJohn Hodge <[email protected]>
Sun, 3 Nov 2013 12:43:35 +0000 (20:43 +0800)
KernelLand/Kernel/include/threads_int.h
KernelLand/Kernel/mutex.c
KernelLand/Kernel/rwlock.c
KernelLand/Kernel/semaphore.c
KernelLand/Kernel/threads.c
KernelLand/Kernel/workqueue.c

index 4b4641c..403a2ef 100644 (file)
@@ -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);
 
index d74cde8..a869df5 100644 (file)
@@ -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 );
        }
index a6aeca8..c39ce10 100644 (file)
@@ -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
        {
index e817574..0b70df5 100644 (file)
@@ -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 );
index 21dc055..a1d3cdb 100644 (file)
@@ -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;
 }
 
 /**
index 2083bde..3e35b06 100644 (file)
@@ -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;
        }
 }
 

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