Kernel - Cleaning up messages
[tpg/acess2.git] / Kernel / threads.c
index ecddf94..4ab76ff 100644 (file)
@@ -7,11 +7,13 @@
 #include <threads.h>
 #include <threads_int.h>
 #include <errno.h>
+#include <mutex.h>
 #include <semaphore.h>
 
 // Configuration
 #define DEBUG_TRACE_TICKETS    0       // Trace ticket counts
 #define DEBUG_TRACE_STATE      0       // Trace state changes (sleep/wake)
+#define SEMAPHORE_DEBUG        0
 
 // --- Schedulers ---
 #define SCHED_UNDEF    0
 #define SCHED_RR_SIM   2       // Single Queue Round Robin
 #define SCHED_RR_PRI   3       // Multi Queue Round Robin
 // Set scheduler type
-#define SCHEDULER_TYPE SCHED_LOTTERY
+#define SCHEDULER_TYPE SCHED_RR_PRI
 
 // === CONSTANTS ===
-#define        DEFAULT_QUANTUM 10
+#define        DEFAULT_QUANTUM 5
 #define        DEFAULT_PRIORITY        5
 #define MIN_PRIORITY           10
 const enum eConfigTypes        cCONFIG_TYPES[] = {
@@ -754,6 +756,56 @@ int Threads_Wake(tThread *Thread)
                SHORTREL( &glThreadListLock );
                return -EOK;
        
+       case THREAD_STAT_SEMAPHORESLEEP: {
+               tSemaphore      *sem;
+               tThread *th, *prev=NULL;
+               
+               sem = Thread->WaitPointer;
+               
+               SHORTLOCK( &sem->Protector );
+               
+               // Remove from sleeping queue
+               for( th = sem->Waiting; th; prev = th, th = th->Next )
+                       if( th == Thread )      break;
+               if( th )
+               {
+                       if(prev)
+                               prev->Next = Thread->Next;
+                       else
+                               sem->Waiting = Thread->Next;
+                       if(sem->LastWaiting == Thread)
+                               sem->LastWaiting = prev;
+               }
+               else
+               {
+                       prev = NULL;
+                       for( th = sem->Signaling; th; prev = th, th = th->Next )
+                               if( th == Thread )      break;
+                       if( !th ) {
+                               Log_Warning("Threads", "Thread %p(%i %s) is not on semaphore %p(%s:%s)",
+                                       Thread, Thread->TID, Thread->ThreadName,
+                                       sem, sem->ModName, sem->Name);
+                               return -EINTERNAL;
+                       }
+                       
+                       if(prev)
+                               prev->Next = Thread->Next;
+                       else
+                               sem->Signaling = Thread->Next;
+                       if(sem->LastSignaling == Thread)
+                               sem->LastSignaling = prev;
+               }
+               
+               SHORTLOCK( &glThreadListLock );
+               Threads_AddActive( Thread );
+               SHORTREL( &glThreadListLock );
+               
+               #if DEBUG_TRACE_STATE
+               Log("Threads_Sleep: %p(%i %s) woken from semaphore", Thread, Thread->TID, Thread->ThreadName);
+               #endif
+               SHORTREL( &sem->Protector );
+               } return -EOK;
+       
        case THREAD_STAT_WAITING:
                Warning("Threads_Wake - Waiting threads are not currently supported");
                return -ENOTIMPL;
@@ -808,14 +860,25 @@ void Threads_AddActive(tThread *Thread)
        
        // Set state
        Thread->Status = THREAD_STAT_ACTIVE;
+//     Thread->CurCPU = -1;
        // Add to active list
-       #if SCHEDULER_TYPE == SCHED_RR_PRI
-       Thread->Next = gaActiveThreads[Thread->Priority];
-       gaActiveThreads[Thread->Priority] = Thread;
-       #else
-       Thread->Next = gActiveThreads;
-       gActiveThreads = Thread;
-       #endif
+       {
+               tThread *tmp, *prev = NULL;
+               #if SCHEDULER_TYPE == SCHED_RR_PRI
+               for( tmp = gaActiveThreads[Thread->Priority]; tmp; prev = tmp, tmp = tmp->Next );
+               if(prev)
+                       prev->Next = Thread;
+               else
+                       gaActiveThreads[Thread->Priority] = Thread;
+               #else
+               for( tmp = gActiveThreads; tmp; prev = tmp, tmp = tmp->Next );
+               if(prev)
+                       prev->Next = Thread;
+               else
+                       gActiveThreads = Thread;
+               #endif
+               Thread->Next = NULL;
+       }
        
        // Update bookkeeping
        giNumActiveThreads ++;
@@ -861,6 +924,9 @@ tThread *Threads_RemActive(void)
        #endif
        {
                SHORTREL( &glThreadListLock );
+               Log_Warning("Threads", "Current thread %p(%i %s) is not on active queue",
+                       ret, ret->TID, ret->ThreadName
+                       );
                return NULL;
        }
        
@@ -898,8 +964,6 @@ void Threads_Fault(int Num)
 {
        tThread *thread = Proc_GetCurThread();
        
-       Log_Log("Threads", "Threads_Fault: thread = %p", thread);
-       
        if(!thread)     return ;
        
        Log_Log("Threads", "Threads_Fault: thread->FaultHandler = %p", thread->FaultHandler);
@@ -1082,6 +1146,7 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
        // Clear Delete Queue
        // - I should probably put this in a worker thread to avoid calling free() in the scheduler
        //   DEFINITELY - free() can deadlock in this case
+       //   I'll do it when it becomes an issue
        while(gDeleteThreads)
        {
                thread = gDeleteThreads->Next;
@@ -1102,7 +1167,10 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
                }
                gDeleteThreads = thread;
        }
-       
+
+       // 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 );
@@ -1417,7 +1485,6 @@ int Semaphore_Wait(tSemaphore *Sem, int MaxToTake)
                else
                        taken = Sem->Value;
                Sem->Value -= taken;
-               SHORTREL( &Sem->Protector );
        }
        else
        {
@@ -1441,16 +1508,16 @@ int Semaphore_Wait(tSemaphore *Sem, int MaxToTake)
                        Sem->LastWaiting = us;
                }
                
-               #if DEBUG_TRACE_STATE
+               #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 );    // Release first to make sure it is released
                SHORTREL( &glThreadListLock );  
-               SHORTREL( &Sem->Protector );
                while(us->Status == THREAD_STAT_SEMAPHORESLEEP) Threads_Yield();
-               // We're only woken when there's something avaliable
+               // We're only woken when there's something avaliable (or a signal arrives)
                us->WaitPointer = NULL;
                
                taken = us->RetStatus;
@@ -1479,7 +1546,7 @@ int Semaphore_Wait(tSemaphore *Sem, int MaxToTake)
                Sem->Value -= given;
                
                
-               #if DEBUG_TRACE_STATE
+               #if DEBUG_TRACE_STATE || SEMAPHORE_DEBUG
                Log("%p (%i %s) woken by wait on %p %s:%s",
                        toWake, toWake->TID, toWake->ThreadName,
                        Sem, Sem->ModName, Sem->Name);
@@ -1541,7 +1608,7 @@ int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd)
                        Sem->LastSignaling = us;
                }
                
-               #if DEBUG_TRACE_STATE
+               #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);
@@ -1593,7 +1660,7 @@ int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd)
                
                if(toWake->bInstrTrace)
                        Log("%s(%i) given %i from %p", toWake->ThreadName, toWake->TID, given, Sem);
-               #if DEBUG_TRACE_STATE
+               #if DEBUG_TRACE_STATE || SEMAPHORE_DEBUG
                Log("%p (%i %s) woken by signal on %p %s:%s",
                        toWake, toWake->TID, toWake->ThreadName,
                        Sem, Sem->ModName, Sem->Name);
@@ -1603,6 +1670,8 @@ int Semaphore_Signal(tSemaphore *Sem, int AmmountToAdd)
                SHORTLOCK( &glThreadListLock );
                if( toWake->Status != THREAD_STAT_ACTIVE )
                        Threads_AddActive(toWake);
+               else
+                       Warning("Thread %p (%i %s) is already awake", toWake, toWake->TID, toWake->ThreadName);
                SHORTREL( &glThreadListLock );
        }
        SHORTREL( &Sem->Protector );

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