extern Uint GetRIP(void); // start.asm
extern Uint64 gInitialPML4[512]; // start.asm
extern char gInitialKernelStack[];
-extern tSpinlock glThreadListLock;
+extern tShortSpinlock glThreadListLock;
extern int giNumCPUs;
extern int giNextTID;
extern int giTotalTickets;
}
#endif
+ // Set Debug registers
+ __asm__ __volatile__ ("mov %0, %%db0" : : "r"(&gThreadZero));
+ __asm__ __volatile__ ("mov %%rax, %%db1" : : "a"(0));
+
gaCPUs[0].Current = &gThreadZero;
gThreadZero.MemState.CR3 = (Uint)gInitialPML4 - KERNEL_BASE;
+ gThreadZero.CurCPU = 0;
// Set timer frequency
outb(0x43, 0x34); // Set Channel 0, Low/High, Rate Generator
// Change Stacks
Proc_ChangeStack();
+
+ Log("Multithreading initialised");
}
#if USE_MP
{
gaCPUs[0].IdleThread = Proc_GetCurThread();
gaCPUs[0].IdleThread->ThreadName = "Idle Thread";
- gaCPUs[0].IdleThread->NumTickets = 0; // Never called randomly
+ Threads_SetPriority( gaCPUs[0].IdleThread, -1 ); // Never called randomly
gaCPUs[0].IdleThread->Quantum = 1; // 1 slice quantum
for(;;) HALT(); // Just yeilds
}
// Set current task
gaCPUs[0].Current = &gThreadZero;
+ gaCPUs[0].Current->CurCPU = 0;
// Start Interrupts (and hence scheduler)
__asm__ __volatile__("sti");
#endif
MM_FinishVirtualInit();
+ Log("Multithreading started");
}
/**
// If the spinlock is set, let it complete
if(IS_LOCKED(&glThreadListLock)) return;
-
+
// Get current thread
thread = gaCPUs[CPU].Current;
// Error Check
if(thread == NULL) {
thread = gaCPUs[CPU].IdleThread;
- Warning("Hmm... Threads_GetNextToRun returned NULL, I don't think this should happen.\n");
+ //Warning("Hmm... Threads_GetNextToRun returned NULL, I don't think this should happen.\n");
+ //LogF("Zzzzz.\n");
return;
}
#if DEBUG_TRACE_SWITCH
- Log("Switching to task %i, CR3 = 0x%x, RIP = %p",
+ LogF("Switching to task %i, CR3 = 0x%x, RIP = %p",
thread->TID,
thread->MemState.CR3,
thread->SavedState.RIP
);
#endif
+
+ if(CPU > MAX_CPUS)
+ LogF("CPU = %i", CPU);
// Set current thread
gaCPUs[CPU].Current = thread;