Skip to content

Commit

Permalink
Kernel/x86_64 - Fix task switching
Browse files Browse the repository at this point in the history
  • Loading branch information
thepowersgang committed Feb 12, 2015
1 parent 14d0ba4 commit 09a0283
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 47 deletions.
2 changes: 2 additions & 0 deletions KernelLand/Kernel/arch/x86_64/lib.c
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions KernelLand/Kernel/arch/x86_64/proc.asm
Expand Up @@ -6,6 +6,8 @@
[section .text]

[extern Threads_Exit]
[extern glThreadListLock]
[extern SHORTREL]

[global GetRIP]
GetRIP:
Expand All @@ -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)
Expand Down
96 changes: 49 additions & 47 deletions KernelLand/Kernel/arch/x86_64/proc.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

/**
Expand Down

0 comments on commit 09a0283

Please sign in to comment.