Merge branch 'master' of git://git.ucc.asn.au/tpg/acess2
[tpg/acess2.git] / KernelLand / Kernel / arch / x86 / proc.c
index 82a3f40..f68e663 100644 (file)
@@ -18,6 +18,7 @@
 #define DEBUG_TRACE_SWITCH     0
 #define DEBUG_DISABLE_DOUBLEFAULT      1
 #define DEBUG_VERY_SLOW_PERIOD 0
+#define DEBUG_NOPREEMPT        1
 
 // === CONSTANTS ===
 // Base is 1193182
@@ -35,6 +36,7 @@ typedef struct sCPU
        Uint8   State;  // 0: Unavaliable, 1: Idle, 2: Active
        Uint16  Resvd;
        tThread *Current;
+       tThread *LastTimerThread;       // Used to do preeemption
 }      tCPU;
 
 // === IMPORTS ===
@@ -465,7 +467,6 @@ void Proc_IdleThread(void *Ptr)
  */
 void Proc_Start(void)
 {
-        int    tid;
        #if USE_MP
         int    i;
        #endif
@@ -477,7 +478,7 @@ void Proc_Start(void)
                if(i)   gaCPUs[i].Current = NULL;
                
                // Create Idle Task
-               tid = Proc_NewKThread(Proc_IdleThread, &gaCPUs[i]);
+               Proc_NewKThread(Proc_IdleThread, &gaCPUs[i]);
                
                // Start the AP
                if( i != giProc_BootProcessorID ) {
@@ -494,8 +495,7 @@ void Proc_Start(void)
        while( giNumInitingCPUs )       __asm__ __volatile__ ("hlt");
        #else
        // Create Idle Task
-       tid = Proc_NewKThread(Proc_IdleThread, &gaCPUs[0]);
-//     gaCPUs[0].IdleThread = Threads_GetThread(tid);
+       Proc_NewKThread(Proc_IdleThread, &gaCPUs[0]);
        
        // Set current task
        gaCPUs[0].Current = &gThreadZero;
@@ -586,9 +586,8 @@ void Proc_ClearThread(tThread *Thread)
 tTID Proc_NewKThread(void (*Fcn)(void*), void *Data)
 {
        Uint    esp;
-       tThread *newThread, *cur;
+       tThread *newThread;
        
-       cur = Proc_GetCurThread();
        newThread = Threads_CloneTCB(0);
        if(!newThread)  return -1;
        
@@ -664,7 +663,7 @@ tPID Proc_Clone(Uint Flags)
  * \fn int Proc_SpawnWorker(void)
  * \brief Spawns a new worker thread
  */
-int Proc_SpawnWorker(void (*Fcn)(void*), void *Data)
+tThread *Proc_SpawnWorker(void (*Fcn)(void*), void *Data)
 {
        tThread *new;
        Uint    stack_contents[4];
@@ -673,7 +672,7 @@ int Proc_SpawnWorker(void (*Fcn)(void*), void *Data)
        new = Threads_CloneThreadZero();
        if(!new) {
                Warning("Proc_SpawnWorker - Out of heap space!\n");
-               return -1;
+               return NULL;
        }
 
        // Create the stack contents
@@ -695,7 +694,7 @@ int Proc_SpawnWorker(void (*Fcn)(void*), void *Data)
        new->Status = THREAD_STAT_PREINIT;
        Threads_AddActive( new );
        
-       return new->TID;
+       return new;
 }
 
 /**
@@ -709,7 +708,7 @@ Uint Proc_MakeUserStack(void)
        
        // Check Prospective Space
        for( i = USER_STACK_SZ >> 12; i--; )
-               if( MM_GetPhysAddr( base + (i<<12) ) != 0 )
+               if( MM_GetPhysAddr( (void*)(base + (i<<12)) ) != 0 )
                        break;
        
        if(i != -1)     return 0;
@@ -861,6 +860,10 @@ void Proc_DumpThreadCPUState(tThread *Thread)
                __asm__ __volatile__ ("mov %%ebp, %0" : "=r" (stack));
                while( maxBacktraceDistance -- )
                {
+                       if( !CheckMem(stack, 8) ) {
+                               regs = NULL;
+                               break;
+                       }
                        // [ebp] = oldEbp
                        // [ebp+4] = retaddr
                        
@@ -939,6 +942,7 @@ void Proc_Reschedule(void)
 
        // Update CPU state
        gaCPUs[cpu].Current = nextthread;
+       gaCPUs[cpu].LastTimerThread = NULL;
        gTSSs[cpu].ESP0 = nextthread->KernelStack-4;
        __asm__ __volatile__("mov %0, %%db0\n\t" : : "r"(nextthread) );
 
@@ -976,49 +980,26 @@ void Proc_Reschedule(void)
  */
 void Proc_Scheduler(int CPU)
 {
-#if 0
-       tThread *thread;
-       
-       // If the spinlock is set, let it complete
-       if(IS_LOCKED(&glThreadListLock))        return;
-       
-       // Get current thread
-       thread = gaCPUs[CPU].Current;
-       
-       if( thread )
-       {
-               tRegs   *regs;
-               Uint    ebp;
-               // Reduce remaining quantum and continue timeslice if non-zero
-               if( thread->Remaining-- )
-                       return;
-               // Reset quantum for next call
-               thread->Remaining = thread->Quantum;
-               
-               // TODO: Make this more stable somehow
-               __asm__ __volatile__("mov %%ebp, %0" : "=r" (ebp));
-               regs = (tRegs*)(ebp+(2+2)*4);   // EBP,Ret + CPU,CurThread
-               thread->SavedState.UserCS = regs->cs;
-               thread->SavedState.UserEIP = regs->eip;
-               
-               if(thread->bInstrTrace) {
-                       regs->eflags |= 0x100;  // Set TF
-                       Log("%p De-scheduled", thread);
-               }
-               else
-                       regs->eflags &= ~0x100; // Clear TF
-       }
-
-       // TODO: Ack timer?
        #if USE_MP
        if( GetCPUNum() )
                gpMP_LocalAPIC->EOI.Val = 0;
        else
        #endif
                outb(0x20, 0x20);
-       __asm__ __volatile__ ("sti");
-       Proc_Reschedule();
-#endif
+       __asm__ __volatile__ ("sti");   
+
+       // Call the timer update code
+       Timer_CallTimers();
+
+       #if !DEBUG_NOPREEMPT
+       // If two ticks happen within the same task, and it's not an idle task, swap
+       if( gaCPUs[CPU].Current->TID > giNumCPUs && gaCPUs[CPU].Current == gaCPUs[CPU].LastTimerThread )
+       {
+               Proc_Reschedule();
+       }
+       
+       gaCPUs[CPU].LastTimerThread = gaCPUs[CPU].Current;
+       #endif
 }
 
 // === EXPORTS ===

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