X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Farch%2Fx86%2Fproc.c;h=281b628879b1b159013b2e1b4004cda194e8ebb7;hb=a3464cb30ecb189019b8bceb70aebdc74f5edded;hp=82a3f40908fb821f08d893ac86cb6d94e10a4cec;hpb=51ab5f489bc356940c95cc936fd0508e8f07ea97;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/arch/x86/proc.c b/KernelLand/Kernel/arch/x86/proc.c index 82a3f409..281b6288 100644 --- a/KernelLand/Kernel/arch/x86/proc.c +++ b/KernelLand/Kernel/arch/x86/proc.c @@ -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 === @@ -939,6 +941,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 +979,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 ===