+ Log(" Just created (unknown %p)", Thread->SavedState.EIP);
+}
+
+void Proc_Reschedule(void)
+{
+ tThread *nextthread, *curthread;
+ int cpu = GetCPUNum();
+
+ // TODO: Wait for the lock?
+ if(IS_LOCKED(&glThreadListLock)) return;
+
+ curthread = Proc_GetCurThread();
+
+ nextthread = Threads_GetNextToRun(cpu, curthread);
+
+ if(!nextthread || nextthread == curthread)
+ return ;
+
+ #if DEBUG_TRACE_SWITCH
+ // HACK: Ignores switches to the idle threads
+ if( nextthread->TID == 0 || nextthread->TID > giNumCPUs )
+ {
+ LogF("\nSwitching CPU %i to %p (%i %s) - CR3 = 0x%x, EIP = %p, ESP = %p\n",
+ GetCPUNum(),
+ nextthread, nextthread->TID, nextthread->ThreadName,
+ nextthread->Process->MemState.CR3,
+ nextthread->SavedState.EIP,
+ nextthread->SavedState.ESP
+ );
+ LogF("OldCR3 = %P\n", curthread->Process->MemState.CR3);
+ }
+ #endif
+
+ // Update CPU state
+ gaCPUs[cpu].Current = nextthread;
+ gTSSs[cpu].ESP0 = nextthread->KernelStack-4;
+ __asm__ __volatile__("mov %0, %%db0\n\t" : : "r"(nextthread) );
+
+ // Save FPU/MMX/XMM/SSE state
+ if( curthread && curthread->SavedState.SSE )
+ {
+ Proc_SaveSSE( ((Uint)curthread->SavedState.SSE + 0xF) & ~0xF );
+ curthread->SavedState.bSSEModified = 0;
+ Proc_DisableSSE();
+ }
+
+ if( curthread )
+ {
+ SwitchTasks(
+ nextthread->SavedState.ESP, &curthread->SavedState.ESP,
+ nextthread->SavedState.EIP, &curthread->SavedState.EIP,
+ nextthread->Process->MemState.CR3
+ );
+ }
+ else
+ {
+ SwitchTasks(
+ nextthread->SavedState.ESP, 0,
+ nextthread->SavedState.EIP, 0,
+ nextthread->Process->MemState.CR3
+ );
+ }
+
+ return ;