Kernel/armv7 - Fixing bugs, Proc_Clone works now
[tpg/acess2.git] / Kernel / threads.c
index 4ab76ff..78e53ac 100644 (file)
@@ -9,6 +9,7 @@
 #include <errno.h>
 #include <mutex.h>
 #include <semaphore.h>
+#include <hal_proc.h>
 
 // Configuration
 #define DEBUG_TRACE_TICKETS    0       // Trace ticket counts
@@ -34,10 +35,6 @@ const enum eConfigTypes      cCONFIG_TYPES[] = {
 };
 
 // === IMPORTS ===
-extern void    ArchThreads_Init(void);
-extern void    Proc_CallFaultHandler(tThread *Thread);
-extern void    Proc_DumpThreadCPUState(tThread *Thread);
-extern int     GetCPUNum(void);
 
 // === PROTOTYPES ===
 void   Threads_Init(void);
@@ -127,6 +124,7 @@ void Threads_Init(void)
        
        Log_Debug("Threads", "Offsets of tThread");
        Log_Debug("Threads", ".Priority = %i", offsetof(tThread, Priority));
+       Log_Debug("Threads", ".KernelStack = %i", offsetof(tThread, KernelStack));
        
        // Create Initial Task
        #if SCHEDULER_TYPE == SCHED_RR_PRI
@@ -235,12 +233,10 @@ void Threads_SetPriority(tThread *Thread, int Pri)
 }
 
 /**
- * \fn tThread *Threads_CloneTCB(Uint *Err, Uint Flags)
  * \brief Clone the TCB of the current thread
- * \param Err  Error pointer
  * \param Flags        Flags for something... (What is this for?)
  */
-tThread *Threads_CloneTCB(Uint *Err, Uint Flags)
+tThread *Threads_CloneTCB(Uint Flags)
 {
        tThread *cur, *new;
         int    i;
@@ -248,7 +244,7 @@ tThread *Threads_CloneTCB(Uint *Err, Uint Flags)
        
        // Allocate and duplicate
        new = malloc(sizeof(tThread));
-       if(new == NULL) { *Err = -ENOMEM; return NULL; }
+       if(new == NULL) { errno = -ENOMEM; return NULL; }
        memcpy(new, cur, sizeof(tThread));
        
        new->CurCPU = -1;
@@ -311,14 +307,12 @@ tThread *Threads_CloneTCB(Uint *Err, Uint Flags)
 }
 
 /**
- * \fn tThread *Threads_CloneTCB(Uint *Err, Uint Flags)
- * \brief Clone the TCB of the current thread
+ * \brief Clone the TCB of the kernel thread
  */
 tThread *Threads_CloneThreadZero(void)
 {
-       tThread *cur, *new;
+       tThread *new;
         int    i;
-       cur = Proc_GetCurThread();
        
        // Allocate and duplicate
        new = malloc(sizeof(tThread));
@@ -345,28 +339,17 @@ tThread *Threads_CloneThreadZero(void)
        new->LastMessage = NULL;
        
        // Set State
-       new->Remaining = new->Quantum = cur->Quantum;
-       new->Priority = cur->Priority;
+       new->Remaining = new->Quantum = DEFAULT_QUANTUM;
+       new->Priority = DEFAULT_PRIORITY;
        new->bInstrTrace = 0;
        
        // Set Signal Handlers
        new->CurFaultNum = 0;
-       new->FaultHandler = cur->FaultHandler;
+       new->FaultHandler = 0;
        
        for( i = 0; i < NUM_CFG_ENTRIES; i ++ )
        {
-               switch(cCONFIG_TYPES[i])
-               {
-               default:
-                       new->Config[i] = cur->Config[i];
-                       break;
-               case CFGT_HEAPSTR:
-                       if(cur->Config[i])
-                               new->Config[i] = (Uint) strdup( (void*)cur->Config[i] );
-                       else
-                               new->Config[i] = 0;
-                       break;
-               }
+               new->Config[i] = 0;
        }
        
        // Maintain a global list of threads
@@ -670,9 +653,10 @@ void Threads_Kill(tThread *Thread, int Status)
        SHORTREL( &Thread->IsLocked );  // TODO: We may not actually be released...
        
        // And, reschedule
-       if(isCurThread) {
+       if(isCurThread)
+       {
                for( ;; )
-                       HALT();
+                       Proc_Reschedule();
        }
 }
 
@@ -681,10 +665,8 @@ void Threads_Kill(tThread *Thread, int Status)
  */
 void Threads_Yield(void)
 {
-       tThread *thread = Proc_GetCurThread();
-       thread->Remaining = 0;
-       //while(thread->Remaining == 0)
-               HALT();
+//     Log("Threads_Yield: by %p", __builtin_return_address(0));
+       Proc_Reschedule();
 }
 
 /**
@@ -720,8 +702,12 @@ void Threads_Sleep(void)
        
        // Release Spinlock
        SHORTREL( &glThreadListLock );
-       
-       while(cur->Status != THREAD_STAT_ACTIVE)        HALT();
+
+       while(cur->Status != THREAD_STAT_ACTIVE) {
+               Proc_Reschedule();
+               if( cur->Status != THREAD_STAT_ACTIVE )
+                       Log("%i - Huh? why am I up? zzzz...", cur->TID);
+       }
 }
 
 
@@ -852,7 +838,8 @@ void Threads_AddActive(tThread *Thread)
        
        if( Thread->Status == THREAD_STAT_ACTIVE ) {
                tThread *cur = Proc_GetCurThread();
-               Warning("WTF, CPU%i %p (%i %s) is adding %p (%i %s) when it is active",
+               Log_Warning("Threads", "WTF, %p CPU%i %p (%i %s) is adding %p (%i %s) when it is active",
+                       __builtin_return_address(0),
                        GetCPUNum(), cur, cur->TID, cur->ThreadName, Thread, Thread->TID, Thread->ThreadName);
                SHORTREL( &glThreadListLock );
                return ;
@@ -907,14 +894,17 @@ void Threads_AddActive(tThread *Thread)
 
 /**
  * \brief Removes the current thread from the active queue
- * \warning This should ONLY be called with task switches disabled
+ * \warning This should ONLY be called with the lock held
  * \return Current thread pointer
  */
 tThread *Threads_RemActive(void)
 {
        tThread *ret = Proc_GetCurThread();
-       
-       SHORTLOCK( &glThreadListLock );
+
+       if( !IS_LOCKED(&glThreadListLock) ) {
+               Log_KernelPanic("Threads", "Threads_RemActive called without lock held");
+               return NULL;
+       }
        
        // Delete from active queue
        #if SCHEDULER_TYPE == SCHED_RR_PRI
@@ -941,8 +931,6 @@ tThread *Threads_RemActive(void)
                GetCPUNum(), ret, ret->TID, ret->ThreadName, giFreeTickets);
        #endif
        
-       SHORTREL( &glThreadListLock );
-       
        return ret;
 }
 
@@ -982,6 +970,7 @@ void Threads_Fault(int Num)
        
        // Double Fault? Oh, F**k
        if(thread->CurFaultNum != 0) {
+               Log_Warning("Threads", "Threads_Fault: Double fault on %i", thread->TID);
                Threads_Kill(thread, -1);       // For now, just kill
                HALT();
        }
@@ -997,7 +986,10 @@ void Threads_Fault(int Num)
  */
 void Threads_SegFault(tVAddr Addr)
 {
-       Warning("Thread #%i committed a segfault at address %p", Proc_GetCurThread()->TID, Addr);
+       tThread *cur = Proc_GetCurThread();
+       cur->bInstrTrace = 0;
+       Log_Warning("Threads", "Thread #%i committed a segfault at address %p", cur->TID, Addr);
+       MM_DumpTables(0, USER_MAX);
        Threads_Fault( 1 );
        //Threads_Exit( 0, -1 );
 }
@@ -1139,7 +1131,6 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
        if( gaThreads_NoTaskSwitch[CPU] )
                return Last;
 
-
        // Lock thread list
        SHORTLOCK( &glThreadListLock );
        
@@ -1291,7 +1282,7 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
                        }
                        // If we fall onto the same queue again, special handling is
                        // needed
-                       if( i == Last->Priority ) {
+                       if( Last && Last->Status == THREAD_STAT_ACTIVE && i == Last->Priority ) {
                                tThread *savedThread = thread;
                                
                                // Find the next unscheduled thread in the list
@@ -1312,6 +1303,9 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
                        SHORTREL(&glThreadListLock);
                        return NULL;
                }
+               if( thread->Status != THREAD_STAT_ACTIVE ) {
+                       LogF("Oops, Thread %i (%s) is not active\n", thread->TID, thread->ThreadName);
+               }
        }
        #elif SCHEDULER_TYPE == SCHED_RR_SIM
        {               
@@ -1341,6 +1335,7 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
        
        // Make the new thread non-schedulable
        thread->CurCPU = CPU;
+       thread->Remaining = thread->Quantum;
        
        SHORTREL( &glThreadListLock );
        

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