X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Farch%2Fx86%2Fproc.c;h=d468d11a215f3b64aaeb40d7f50cf2a19586219e;hb=ab4180ab19a5b2b096f137c3d56d771a70e159df;hp=31eb0557d8ad35e5425e608fc3d996c82cb4b317;hpb=f119d0e5b18b7286d04fc536a94e0f96e3c51714;p=tpg%2Facess2.git diff --git a/Kernel/arch/x86/proc.c b/Kernel/arch/x86/proc.c index 31eb0557..d468d11a 100644 --- a/Kernel/arch/x86/proc.c +++ b/Kernel/arch/x86/proc.c @@ -24,9 +24,12 @@ extern int giNumCPUs; extern int giNextTID; extern int giTotalTickets; extern int giNumActiveThreads; +extern tThread gThreadZero; extern tThread *gActiveThreads; extern tThread *gSleepingThreads; extern tThread *gDeleteThreads; +extern tThread *Threads_GetNextToRun(int CPU); +extern void Threads_Dump(); // === PROTOTYPES === void ArchThreads_Init(); @@ -38,7 +41,7 @@ void Proc_Scheduler(); // === GLOBALS === // --- Current State --- #if USE_MP -tThread **gCurrentThread = NULL; +tThread *gCurrentThread[MAX_CPUS] = {NULL}; #else tThread *gCurrentThread = NULL; #endif @@ -123,6 +126,20 @@ void ArchThreads_Init() } #endif + #if USE_MP + gCurrentThread[0] = &gThreadZero; + #else + gCurrentThread = &gThreadZero; + #endif + + #if USE_PAE + gThreadZero.MemState.PDP[0] = 0; + gThreadZero.MemState.PDP[1] = 0; + gThreadZero.MemState.PDP[2] = 0; + #else + gThreadZero.MemState.CR3 = (Uint)gaInitPageDir - KERNEL_BASE; + #endif + // Set timer frequency outb(0x43, 0x34); // Set Channel 0, Low/High, Rate Generator outb(0x40, TIMER_DIVISOR&0xFF); // Low Byte of Divisor @@ -133,7 +150,14 @@ void ArchThreads_Init() // Change Stacks Proc_ChangeStack(); - +} + +/** + * \fn void Proc_Start() + * \brief Start process scheduler + */ +void Proc_Start() +{ // Start Interrupts (and hence scheduler) __asm__ __volatile__("sti"); } @@ -174,7 +198,7 @@ void Proc_ChangeStack() return; } - curBase = gCurrentThread->KernelStack; + curBase = (Uint)&Kernel_Stack_Top; LOG("curBase = 0x%x, newBase = 0x%x", curBase, newBase); @@ -289,61 +313,11 @@ int Proc_Clone(Uint *Err, Uint Flags) giTotalTickets += newThread->NumTickets; RELEASE( &giThreadListLock ); - return newThread->TID; -} - -#if 0 -/** - * \fn void Proc_SetSignalHandler(int Num, void *Handler) - * \brief Sets the signal handler for a signal - */ -void Proc_SetSignalHandler(int Num, void *Handler) -{ - if(Num < 0 || Num >= NSIG) return; + Threads_Dump(); - gCurrentThread->SignalHandlers[Num] = Handler; -} - -/** - * \fn void Proc_SendSignal(int TID, int Num) - */ -void Proc_SendSignal(int TID, int Num) -{ - tThread *thread = Proc_GetThread(TID); - void *handler; - - if(!thread) return ; - - handler = thread->SignalHandlers[Num]; - - // Panic? - if(handler == SIG_ERR) { - Proc_Kill(TID); - return ; - } - // Dump Core? - if(handler == -2) { - Proc_Kill(TID); - return ; - } - // Ignore? - if(handler == -2) return; - - // Check the type and handle if the thread is already in a signal - if(thread->CurSignal != 0) { - if(Num < _SIGTYPE_FATAL) - Proc_Kill(TID); - } else { - while(thread->CurSignal != 0) - Proc_Yield(); - } - } - - //TODO: + return newThread->TID; } -#endif - /** * \fn Uint Proc_MakeUserStack() * \brief Creates a new user stack @@ -475,7 +449,6 @@ int Proc_Demote(Uint *Err, int Dest, tRegs *Regs) void Proc_Scheduler(int CPU) { Uint esp, ebp, eip; - Uint number, ticket; tThread *thread; // If the spinlock is set, let it complete @@ -494,12 +467,12 @@ void Proc_Scheduler(int CPU) // Check if there is any tasks running if(giNumActiveThreads == 0) { - Log("No Active threads, sleeping\n"); + Log("No Active threads, sleeping"); __asm__ __volatile__ ("hlt"); return; } - // Reduce remaining quantum + // Reduce remaining quantum and continue timeslice if non-zero if(gCurrentThread->Remaining--) return; // Reset quantum for next call gCurrentThread->Remaining = gCurrentThread->Quantum; @@ -515,34 +488,13 @@ void Proc_Scheduler(int CPU) gCurrentThread->SavedState.EBP = ebp; gCurrentThread->SavedState.EIP = eip; - // Special case: 1 thread - if(giNumActiveThreads == 1) - { - // Check if a switch is needed (NumActive can be 1 after a sleep) - if(gActiveThreads == gCurrentThread) return; - // Switch processes - gCurrentThread = gActiveThreads; - goto performSwitch; - } - - // Get the ticket number - ticket = number = rand() % giTotalTickets; - - // Find the next thread - for(thread=gActiveThreads;thread;thread=thread->Next) - { - if(thread->NumTickets > number) break; - number -= thread->NumTickets; - } + // Get next thread + thread = Threads_GetNextToRun(CPU); // Error Check - if(thread == NULL) - { - number = 0; - for(thread=gActiveThreads;thread;thread=thread->Next) - number += thread->NumTickets; - Panic("Bookeeping Failed - giTotalTicketCount (%i) != true count (%i)", - giTotalTickets, number); + if(thread == NULL) { + Warning("Hmm... Threads_GetNextToRun returned NULL, I don't think this should happen.\n"); + return; } // Set current thread @@ -551,9 +503,7 @@ void Proc_Scheduler(int CPU) // Update Kernel Stack pointer gTSSs[CPU].ESP0 = thread->KernelStack; -performSwitch: // Set address space - //MM_SetCR3( gCurrentThread->CR3 ); __asm__ __volatile__ ("mov %0, %%cr3"::"a"(gCurrentThread->MemState.CR3)); // Switch threads __asm__ __volatile__ (