Kernel/x86_64 - Fix task switching
authorJohn Hodge <[email protected]>
Thu, 12 Feb 2015 04:18:40 +0000 (12:18 +0800)
committerJohn Hodge <[email protected]>
Thu, 12 Feb 2015 04:18:40 +0000 (12:18 +0800)
KernelLand/Kernel/arch/x86_64/lib.c
KernelLand/Kernel/arch/x86_64/proc.asm
KernelLand/Kernel/arch/x86_64/proc.c

index 85dda82..60770f6 100644 (file)
@@ -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
index aff670a..afde354 100644 (file)
@@ -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)
index 50b5054..7c73bf9 100644 (file)
@@ -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);
 }
 
 /**

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