From 09a02836dd9b51edc0f9fc73375fa9d90252a97d Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 12 Feb 2015 12:18:40 +0800 Subject: [PATCH] Kernel/x86_64 - Fix task switching --- KernelLand/Kernel/arch/x86_64/lib.c | 2 + KernelLand/Kernel/arch/x86_64/proc.asm | 5 ++ KernelLand/Kernel/arch/x86_64/proc.c | 96 +++++++++++++------------- 3 files changed, 56 insertions(+), 47 deletions(-) diff --git a/KernelLand/Kernel/arch/x86_64/lib.c b/KernelLand/Kernel/arch/x86_64/lib.c index 85dda824..60770f63 100644 --- a/KernelLand/Kernel/arch/x86_64/lib.c +++ b/KernelLand/Kernel/arch/x86_64/lib.c @@ -88,6 +88,8 @@ void SHORTLOCK(struct sShortSpinlock *Lock) Lock->Depth ++; return ; } + #else + ASSERT( !CPU_HAS_LOCK(Lock) ); #endif // Wait for another CPU to release diff --git a/KernelLand/Kernel/arch/x86_64/proc.asm b/KernelLand/Kernel/arch/x86_64/proc.asm index aff670ac..afde3544 100644 --- a/KernelLand/Kernel/arch/x86_64/proc.asm +++ b/KernelLand/Kernel/arch/x86_64/proc.asm @@ -6,6 +6,8 @@ [section .text] [extern Threads_Exit] +[extern glThreadListLock] +[extern SHORTREL] [global GetRIP] GetRIP: @@ -18,6 +20,9 @@ NewTaskHeader: ; [rsp+0x08]: Function ; [rsp+0x10]: Argument + mov rdi, glThreadListLock + call SHORTREL + mov rdi, [rsp+0x10] mov rax, [rsp+0x8] add rsp, 0x10 ; Reclaim stack space (thread/fcn) diff --git a/KernelLand/Kernel/arch/x86_64/proc.c b/KernelLand/Kernel/arch/x86_64/proc.c index 50b50548..7c73bf9f 100644 --- a/KernelLand/Kernel/arch/x86_64/proc.c +++ b/KernelLand/Kernel/arch/x86_64/proc.c @@ -508,7 +508,10 @@ tTID Proc_Clone(Uint Flags) // Save core machine state rip = Proc_CloneInt(&newThread->SavedState.RSP, &newThread->Process->MemState.CR3, !!(Flags & CLONE_NOUSER)); - if(rip == 0) return 0; // Child + if(rip == 0) { + SHORTREL(&glThreadListLock); + return 0; // Child + } newThread->KernelStack = cur->KernelStack; newThread->SavedState.RIP = rip; newThread->SavedState.SSE = NULL; @@ -735,62 +738,61 @@ void Proc_DumpThreadCPUState(tThread *Thread) void Proc_Reschedule(void) { - tThread *nextthread, *curthread; int cpu = GetCPUNum(); - // TODO: Wait for it? - if(IS_LOCKED(&glThreadListLock)) return; - - curthread = gaCPUs[cpu].Current; - - nextthread = Threads_GetNextToRun(cpu, curthread); + if(CPU_HAS_LOCK(&glThreadListLock)) + return; + SHORTLOCK(&glThreadListLock); - if(nextthread == curthread) return ; + tThread *curthread = gaCPUs[cpu].Current; + tThread *nextthread = Threads_GetNextToRun(cpu, curthread); + if(!nextthread) nextthread = gaCPUs[cpu].IdleThread; - if(!nextthread) - return ; - - #if DEBUG_TRACE_SWITCH - LogF("\nSwitching to task CR3 = 0x%x, RIP = %p, RSP = %p - %i (%s)\n", - nextthread->Process->MemState.CR3, - nextthread->SavedState.RIP, - nextthread->SavedState.RSP, - nextthread->TID, - nextthread->ThreadName - ); - #endif - - // Update CPU state - gaCPUs[cpu].Current = nextthread; - gTSSs[cpu].RSP0 = nextthread->KernelStack-sizeof(void*); - __asm__ __volatile__ ("mov %0, %%db0" : : "r" (nextthread)); - if( curthread ) + if(nextthread && nextthread != curthread) { - // Save FPU/MMX/XMM/SSE state - if( curthread->SavedState.SSE ) + #if DEBUG_TRACE_SWITCH + LogF("\nSwitching to task CR3 = 0x%x, RIP = %p, RSP = %p - %i (%s)\n", + nextthread->Process->MemState.CR3, + nextthread->SavedState.RIP, + nextthread->SavedState.RSP, + nextthread->TID, + nextthread->ThreadName + ); + #endif + + // Update CPU state + gaCPUs[cpu].Current = nextthread; + gTSSs[cpu].RSP0 = nextthread->KernelStack-sizeof(void*); + __asm__ __volatile__ ("mov %0, %%db0" : : "r" (nextthread)); + + if( curthread ) { - Proc_SaveSSE( ((Uint)curthread->SavedState.SSE + 0xF) & ~0xF ); - curthread->SavedState.bSSEModified = 0; - Proc_DisableSSE(); + // Save FPU/MMX/XMM/SSE state + if( curthread->SavedState.SSE ) + { + Proc_SaveSSE( ((Uint)curthread->SavedState.SSE + 0xF) & ~0xF ); + curthread->SavedState.bSSEModified = 0; + Proc_DisableSSE(); + } + SwitchTasks( + nextthread->SavedState.RSP, &curthread->SavedState.RSP, + nextthread->SavedState.RIP, &curthread->SavedState.RIP, + nextthread->Process->MemState.CR3 + ); + } + else + { + Uint tmp; + SwitchTasks( + nextthread->SavedState.RSP, &tmp, + nextthread->SavedState.RIP, &tmp, + nextthread->Process->MemState.CR3 + ); } - SwitchTasks( - nextthread->SavedState.RSP, &curthread->SavedState.RSP, - nextthread->SavedState.RIP, &curthread->SavedState.RIP, - nextthread->Process->MemState.CR3 - ); - } - else - { - Uint tmp; - SwitchTasks( - nextthread->SavedState.RSP, &tmp, - nextthread->SavedState.RIP, &tmp, - nextthread->Process->MemState.CR3 - ); } - return ; + SHORTREL(&glThreadListLock); } /** -- 2.20.1