Kernel/threads - Debug cleanups and (hopefully) race avoidance
[tpg/acess2.git] / KernelLand / Kernel / threads.c
index 80b2796..9aefeab 100644 (file)
@@ -4,6 +4,7 @@
  * threads.c
  * - Common Thread Control
  */
+#define DEBUG  0
 #include <acess.h>
 #include <threads.h>
 #include <threads_int.h>
@@ -329,11 +330,10 @@ void Threads_SetPriority(tThread *Thread, int Pri)
  */
 tThread *Threads_CloneTCB(Uint Flags)
 {
-       tThread *cur, *new;
-       cur = Proc_GetCurThread();
+       tThread *cur = Proc_GetCurThread();
        
        // Allocate and duplicate
-       new = malloc(sizeof(tThread));
+       tThread *new = malloc(sizeof(tThread));
        if(new == NULL) { errno = -ENOMEM; return NULL; }
        memcpy(new, cur, sizeof(tThread));
        
@@ -493,7 +493,13 @@ tTID Threads_WaitTID(int TID, int *Status)
                        
                        ret = dead_thread->TID;
                        // - Mark as dead (as opposed to undead)
-                       ASSERTC(dead_thread->Status, ==, THREAD_STAT_ZOMBIE);
+                       if( dead_thread->Status != THREAD_STAT_ZOMBIE ) {
+                               Log_Error("Thread", "Thread %p(%i %s) is not ZOMBIE, instead %s",
+                                       dead_thread, dead_thread->TID, dead_thread->ThreadName,
+                                       (dead_thread->Status < ciTHREAD_STAT_COUNT ? casTHREAD_STAT[dead_thread->Status] : "?")
+                                       );
+                               ASSERTC(dead_thread->Status, ==, THREAD_STAT_ZOMBIE);
+                       }
                        dead_thread->Status = THREAD_STAT_DEAD;
                        // - Set return status
                        if(Status)
@@ -503,7 +509,7 @@ tTID Threads_WaitTID(int TID, int *Status)
                }
                else
                {
-                       Log_Error("Threads", "TODO: Threads_WaitTID(TID=-1) - Any Child");
+                       Log_Error("Threads", "TODO: Threads_WaitTID(TID=-1) - Woken with no child");
                }
                return ret;
        }
@@ -627,17 +633,13 @@ void Threads_Exit(int TID, int Status)
  */
 void Threads_Kill(tThread *Thread, int Status)
 {
-       tMsg    *msg;
         int    isCurThread = Thread == Proc_GetCurThread();
        
        // TODO: Disown all children?
        #if 1
        {
-               tThread *child;
                // TODO: I should keep a .Children list
-               for(child = gAllThreads;
-                       child;
-                       child = child->GlobalNext)
+               for(tThread* child = gAllThreads; child; child = child->GlobalNext)
                {
                        if(child->Parent == Thread)
                                child->Parent = &gThreadZero;
@@ -653,7 +655,7 @@ void Threads_Kill(tThread *Thread, int Status)
        // Clear Message Queue
        while( Thread->Messages )
        {
-               msg = Thread->Messages->Next;
+               tMsg    *msg = Thread->Messages->Next;
                free( Thread->Messages );
                Thread->Messages = msg;
        }
@@ -701,8 +703,8 @@ void Threads_Kill(tThread *Thread, int Status)
                if( !Threads_int_DelFromQueue( &gSleepingThreads, Thread ) )
                {
                        Log_Warning("Threads",
-                               "Threads_Kill - Thread %p(%i,%s) marked as sleeping, but not on list",
-                               Thread, Thread->TID, Thread->ThreadName
+                               "Threads_Kill - Thread "PRIthread_fmt" marked as sleeping, but not on list",
+                               PRIthread_args(Thread)
                                );
                }
                break;
@@ -724,8 +726,6 @@ void Threads_Kill(tThread *Thread, int Status)
        // Save exit status
        Thread->RetStatus = Status;
 
-       SHORTREL( &Thread->IsLocked );
-
        Thread->Status = THREAD_STAT_ZOMBIE;
        SHORTREL( &glThreadListLock );
        // TODO: It's possible that we could be timer-preempted here, should disable that... somehow
@@ -735,7 +735,10 @@ void Threads_Kill(tThread *Thread, int Status)
        Threads_PostEvent( Thread->Parent, THREAD_EVENT_DEADCHILD );
        
        // Process cleanup happens on reaping
-       Log("Thread %i went *hurk* (%i)", Thread->TID, Status);
+       Log("Thread "PRIthread_fmt" went *hurk* (%i) (isCurThread=%B)", PRIthread_args(Thread), Status, isCurThread);
+       //Log("Thread status = %i %s", Thread->Status, casTHREAD_STAT[Thread->Status]);
+       
+       SHORTREL( &Thread->IsLocked );
        
        // And, reschedule
        if(isCurThread)
@@ -760,6 +763,7 @@ void Threads_Yield(void)
 void Threads_int_WaitForStatusEnd(enum eThreadStatus Status)
 {
        tThread *us = Proc_GetCurThread();
+       LOG("us = %p(%i %s), status=%i", us, us->TID, us->ThreadName, Status);
        ASSERT(Status != THREAD_STAT_ACTIVE);
        ASSERT(Status != THREAD_STAT_DEAD);
        while( us->Status == Status )
@@ -1472,6 +1476,7 @@ tThread *Threads_int_GetRunnable(void)
        // Single-list round-robin
        // -----------------------------------
        tThread *thread = gActiveThreads.Head;
+       LOG("thread = %p", thread);
        if( thread )
        {
                gActiveThreads.Head = thread->Next;
@@ -1493,23 +1498,20 @@ tThread *Threads_int_GetRunnable(void)
  */
 tThread *Threads_GetNextToRun(int CPU, tThread *Last)
 {
-       // If this CPU has the lock, we must let it complete
-       if( CPU_HAS_LOCK( &glThreadListLock ) )
-               return Last;
+       ASSERT( CPU_HAS_LOCK(&glThreadListLock) );
        
        // Don't change threads if the current CPU has switches disabled
-       if( gaThreads_NoTaskSwitch[CPU] )
+       if( gaThreads_NoTaskSwitch[CPU] ) {
+               LOG("- Denied");
                return Last;
-
-       // Lock thread list
-       SHORTLOCK( &glThreadListLock );
+       }
        
        // Make sure the current (well, old) thread is marked as de-scheduled   
        if(Last)        Last->CurCPU = -1;
 
        // No active threads, just take a nap
        if(giNumActiveThreads == 0) {
-               SHORTREL( &glThreadListLock );
+               LOG("- No active");
                #if DEBUG_TRACE_TICKETS
                Log("No active threads");
                #endif
@@ -1552,7 +1554,7 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
 
        // Call actual scheduler        
        tThread *thread = Threads_int_GetRunnable();
-               
+       
        // Anything to do?
        if( thread )
        {
@@ -1578,8 +1580,6 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
                Warning("No runnable thread for CPU%i", CPU);
        }
        
-       SHORTREL( &glThreadListLock );
-       
        return thread;
 }
 

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