From: John Hodge Date: Sun, 8 Feb 2015 05:57:42 +0000 (+0800) Subject: Kernel/x86 - Clean up some of the task switching code (possibly a little broken) X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=14d0ba44433f0f828aff710184fd3c597ab73999;p=tpg%2Facess2.git Kernel/x86 - Clean up some of the task switching code (possibly a little broken) --- diff --git a/KernelLand/Kernel/arch/x86/common.inc.asm b/KernelLand/Kernel/arch/x86/common.inc.asm new file mode 100644 index 00000000..ec7f8441 --- /dev/null +++ b/KernelLand/Kernel/arch/x86/common.inc.asm @@ -0,0 +1,24 @@ +%macro PUSH_CC 0 + ; Don't bother being too picky, just take the time + pusha +%endmacro +%macro PUSH_SEG 0 + push ds + push es + push fs + push gs + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax +%endmacro +%macro POP_CC 0 + popa +%endmacro +%macro POP_SEG 0 + pop gs + pop fs + pop es + pop ds +%endmacro diff --git a/KernelLand/Kernel/arch/x86/desctab.asm b/KernelLand/Kernel/arch/x86/desctab.asm index 354a001e..33825347 100644 --- a/KernelLand/Kernel/arch/x86/desctab.asm +++ b/KernelLand/Kernel/arch/x86/desctab.asm @@ -1,6 +1,7 @@ ; AcessOS Microkernel Version ; ; desctab.asm +%include "arch/x86/common.inc.asm" [BITS 32] @@ -182,14 +183,14 @@ Isr0xED: jmp .jmp [global Isr0xEE] -[extern SchedulerBase] +[extern Proc_EventTimer_LAPIC] ; AP's Timer Interrupt Isr0xEE: push eax ; Line up with interrupt number mov eax, dr1 ; CPU Number push eax mov eax, [esp+4] ; Load EAX back - jmp SchedulerBase + jmp Proc_EventTimer_LAPIC ; Spurious Interrupt [global Isr0xEF] Isr0xEF: @@ -201,7 +202,7 @@ Isr0xEF: ; - Timer [global Isr240] [global Isr240.jmp] -[extern SchedulerBase] +[extern Proc_EventTimer_PIT] [extern SetAPICTimerCount] Isr240: push 0 ; Line up with Argument in errors @@ -211,7 +212,7 @@ Isr240.jmp: %if USE_MP jmp SetAPICTimerCount ; This is reset once the bus speed has been calculated %else - jmp SchedulerBase + jmp Proc_EventTimer_PIT %endif ; - Assignable %assign i 0xF1 @@ -254,11 +255,8 @@ ErrorCommon: ; -------------------------- [extern SyscallHandler] SyscallCommon: - pusha - push ds - push es - push fs - push gs + PUSH_CC ; Actually a pusha + PUSH_SEG push esp call SyscallHandler @@ -286,17 +284,8 @@ SyscallCommon: [global IRQCommon_handled] IRQCommon_handled equ IRQCommon.handled IRQCommon: - pusha - push ds - push es - push fs - push gs - - mov ax, 0x10 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax + PUSH_CC + PUSH_SEG push esp call IRQ_Handler diff --git a/KernelLand/Kernel/arch/x86/proc.asm b/KernelLand/Kernel/arch/x86/proc.asm index be4c10d3..1987166d 100644 --- a/KernelLand/Kernel/arch/x86/proc.asm +++ b/KernelLand/Kernel/arch/x86/proc.asm @@ -1,5 +1,6 @@ ; AcessOS Microkernel Version ; Start.asm +%include "arch/x86/common.inc.asm" [bits 32] @@ -11,19 +12,6 @@ KSTACK_USERSTATE_SIZE equ (4+8+1+5)*4 ; SRegs, GPRegs, CPU, IRET [section .text] -[global NewTaskHeader] -NewTaskHeader: - mov eax, [esp] - mov dr0, eax - - mov eax, [esp+4] - add esp, 12 ; Thread, Function, Arg Count - call eax - - push eax ; Ret val - push 0 ; 0 = This Thread - call Threads_Exit - [extern MM_Clone] [global Proc_CloneInt] Proc_CloneInt: @@ -53,7 +41,7 @@ Proc_CloneInt: ; +16 = Old RIP save loc ; +20 = CR3 SwitchTasks: - pusha + PUSH_CC ; Old IP mov eax, [esp+0x20+16] @@ -78,7 +66,7 @@ SwitchTasks: jmp ecx .restore: - popa + POP_CC xor eax, eax ret @@ -122,17 +110,8 @@ Proc_RestoreSSE: [extern Isr240.jmp] [global SetAPICTimerCount] SetAPICTimerCount: - pusha - push ds - push es - push fs - push gs - - mov ax, 0x10 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax + PUSH_CC + PUSH_SEG mov eax, [gpMP_LocalAPIC] mov ecx, [eax+0x320] @@ -152,7 +131,7 @@ SetAPICTimerCount: mov DWORD [eax+0x380], 0 ; Update Timer IRQ to the IRQ code - mov eax, SchedulerBase + mov eax, Proc_EventTimer_PIT sub eax, Isr240.jmp+5 mov DWORD [Isr240.jmp+1], eax @@ -160,72 +139,55 @@ SetAPICTimerCount: .ret: mov dx, 0x20 mov al, 0x20 - out dx, al ; ACK IRQ - pop gs - pop fs - pop es - pop ds - popa + out 0x20, al ; ACK IRQ + POP_SEG + POP_CC add esp, 8 ; CPU ID / Error Code iret %endif -; -------------- -; Task Scheduler -; -------------- -[extern Proc_Scheduler] -[global SchedulerBase] -SchedulerBase: - pusha - push ds - push es - push fs - push gs + +%if USE_MP +[global Proc_EventTimer_LAPIC] +Proc_EventTimer_LAPIC: + push eax + mov eax, SS:[gpMP_LocalAPIC] + mov DWORD SS:[eax + 0xB0], 0 + pop eax + jmp Proc_EventTimer_Common +%endif +[global Proc_EventTimer_PIT] +Proc_EventTimer_PIT: + push eax + mov al, 0x20 + out 0x20, al ; ACK IRQ + pop eax + jmp Proc_EventTimer_Common +[extern Proc_HandleEventTimer] +[global Proc_EventTimer_Common] +Proc_EventTimer_Common: + PUSH_CC + PUSH_SEG + ; Clear the Trace/Trap flag pushf and BYTE [esp+1], 0xFE ; Clear Trap Flag popf - - mov eax, dr0 - push eax ; Debug Register 0, Current Thread - - mov ax, 0x10 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax + ; Re-enable interrupts + ; - TODO: This is quite likely racy, if we get an interrupt flood + sti %if USE_MP call GetCPUNum - mov ebx, eax push eax ; Push as argument %else push 0 %endif - call Proc_Scheduler + call Proc_HandleEventTimer [global scheduler_return] scheduler_return: ; Used by some hackery in Proc_DumpThreadCPUState - add esp, 4 ; Remove CPU Number (thread is poped later) - %if USE_MP - test ebx, ebx - jnz .sendEOI - %endif - - mov al, 0x20 - out 0x20, al ; ACK IRQ - - %if USE_MP - jmp .ret -.sendEOI: - mov eax, DWORD [gpMP_LocalAPIC] - mov DWORD [eax+0x0B0], 0 - %endif -.ret: - pop eax ; Debug Register 0, Current Thread - mov dr0, eax - jmp ReturnFromInterrupt ; diff --git a/KernelLand/Kernel/arch/x86/proc.c b/KernelLand/Kernel/arch/x86/proc.c index 999ac679..b1dcb99d 100644 --- a/KernelLand/Kernel/arch/x86/proc.c +++ b/KernelLand/Kernel/arch/x86/proc.c @@ -44,7 +44,6 @@ extern tGDT gGDT[]; extern tIDT gIDT[]; extern void APWait(void); // 16-bit AP pause code extern void APStartup(void); // 16-bit AP startup code -extern void NewTaskHeader(tThread *Thread, void *Fcn, int nArgs, ...); // Actually takes cdecl args extern Uint Proc_CloneInt(Uint *ESP, Uint32 *CR3, int bNoUserClone); extern Uint32 gaInitPageDir[1024]; // start.asm extern char Kernel_Stack_Top[]; @@ -71,6 +70,7 @@ void Proc_IdleThread(void *Ptr); //tThread *Proc_GetCurThread(void); void Proc_ChangeStack(void); // int Proc_NewKThread(void (*Fcn)(void*), void *Data); +void NewTaskHeader(tThread *Thread, void (*Fcn)(void*), void *Data); // Actually takes cdecl args // int Proc_Clone(Uint *Err, Uint Flags); Uint Proc_MakeUserStack(void); //void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize); @@ -78,7 +78,7 @@ void Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP) NO void Proc_CallUser(Uint32 UserIP, Uint32 UserSP, const void *StackData, size_t StackDataLen); //void Proc_CallFaultHandler(tThread *Thread); //void Proc_DumpThreadCPUState(tThread *Thread); -void Proc_Scheduler(int CPU); +void Proc_HandleEventTimer(int CPU); // === GLOBALS === // --- Multiprocessing --- @@ -307,10 +307,12 @@ void Proc_IdleThread(void *Ptr) cpu->Current->ThreadName = strdup("Idle Thread"); Threads_SetPriority( cpu->Current, -1 ); // Never called randomly cpu->Current->Quantum = 1; // 1 slice quantum - for(;;) { + LOG("Idle thread for CPU %i ready", GetCPUNum()); + for(;;) + { __asm__ __volatile__ ("sti"); // Make sure interrupts are enabled - __asm__ __volatile__ ("hlt"); - Proc_Reschedule(); + Proc_Reschedule(); // Reshedule + __asm__ __volatile__ ("hlt"); // And wait for an interrupt if we get scheduled again } } @@ -432,10 +434,7 @@ void Proc_ClearThread(tThread *Thread) tTID Proc_NewKThread(void (*Fcn)(void*), void *Data) { - Uint esp; - tThread *newThread; - - newThread = Threads_CloneTCB(0); + tThread *newThread = Threads_CloneTCB(0); if(!newThread) return -1; // Create new KStack @@ -445,12 +444,14 @@ tTID Proc_NewKThread(void (*Fcn)(void*), void *Data) free(newThread); return -1; } + + LOG("%p(%i %s) SP=%p", newThread, newThread->TID, newThread->ThreadName, newThread->KernelStack); - esp = newThread->KernelStack; + Uint esp = newThread->KernelStack; *(Uint*)(esp-=4) = (Uint)Data; // Data (shadowed) - *(Uint*)(esp-=4) = 1; // Number of params *(Uint*)(esp-=4) = (Uint)Fcn; // Function to call *(Uint*)(esp-=4) = (Uint)newThread; // Thread ID + *(Uint*)(esp-=4) = (Uint)0; // Empty return address newThread->SavedState.ESP = esp; newThread->SavedState.EIP = (Uint)&NewTaskHeader; @@ -463,13 +464,16 @@ tTID Proc_NewKThread(void (*Fcn)(void*), void *Data) return newThread->TID; } -#if 0 -tPID Proc_NewProcess(Uint Flags, void (*Fcn)(void*), size_t SaveSize, const void *Data) +void NewTaskHeader(tThread *NewThread, void (*Fcn)(void*), void *Data) { - tThread *newThread = Threads_CloneTCB(CLONE_VM); - return 0; + LOG("NewThread=%p, Fcn=%p, Data=%p", NewThread, Fcn, Data); + __asm__ __volatile__ ("mov %0, %%dr0" : : "r"(NewThread)); + SHORTREL(&glThreadListLock); + Fcn(Data); + + Threads_Exit(0, 0); + for(;;); } -#endif /** * \fn int Proc_Clone(Uint *Err, Uint Flags) @@ -477,9 +481,7 @@ tPID Proc_NewProcess(Uint Flags, void (*Fcn)(void*), size_t SaveSize, const void */ tPID Proc_Clone(Uint Flags) { - tThread *newThread; tThread *cur = Proc_GetCurThread(); - Uint eip; // Sanity, please if( !(Flags & CLONE_VM) ) { @@ -488,17 +490,17 @@ tPID Proc_Clone(Uint Flags) } // New thread - newThread = Threads_CloneTCB(Flags); + tThread *newThread = Threads_CloneTCB(Flags); if(!newThread) return -1; ASSERT(newThread->Process); - //ASSERT(CheckMem(newThread->Process, sizeof(tProcess))); - //LOG("newThread->Process = %p", newThread->Process); newThread->KernelStack = cur->KernelStack; // Clone state - eip = Proc_CloneInt(&newThread->SavedState.ESP, &newThread->Process->MemState.CR3, Flags & CLONE_NOUSER); + Uint eip = Proc_CloneInt(&newThread->SavedState.ESP, &newThread->Process->MemState.CR3, Flags & CLONE_NOUSER); if( eip == 0 ) { + SHORTREL( &glThreadListLock ); + LOG("In new thread"); return 0; } //ASSERT(newThread->Process); @@ -536,12 +538,13 @@ tThread *Proc_SpawnWorker(void (*Fcn)(void*), void *Data) Warning("Proc_SpawnWorker - Out of heap space!\n"); return NULL; } + LOG("new = (%i %s)", new->TID, new->ThreadName); // Create the stack contents stack_contents[3] = (Uint)Data; - stack_contents[2] = 1; - stack_contents[1] = (Uint)Fcn; - stack_contents[0] = (Uint)new; + stack_contents[2] = (Uint)Fcn; + stack_contents[1] = (Uint)new; + stack_contents[0] = 0; // Create a new worker stack (in PID0's address space) new->KernelStack = MM_NewWorkerStack(stack_contents, sizeof(stack_contents)); @@ -774,82 +777,82 @@ void Proc_DumpThreadCPUState(tThread *Thread) void Proc_Reschedule(void) { - tThread *nextthread, *curthread; int cpu = GetCPUNum(); // TODO: Wait for the lock? - if(IS_LOCKED(&glThreadListLock)) return; + if(IS_LOCKED(&glThreadListLock)) { + LOG("Thread list locked, not rescheduling"); + 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 ) + SHORTLOCK(&glThreadListLock); + + tThread *curthread = Proc_GetCurThread(); + tThread *nextthread = Threads_GetNextToRun(cpu, curthread); + + if(nextthread && nextthread != curthread) { - 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 + #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(" from %p (%i %s) - CR3 = 0x%x, EIP = %p, ESP = %p\n", + curthread, curthread->TID, curthread->ThreadName, + curthread->Process->MemState.CR3, + curthread->SavedState.EIP, + curthread->SavedState.ESP + ); + } + #endif - // Update CPU state - gaCPUs[cpu].Current = nextthread; - gaCPUs[cpu].LastTimerThread = NULL; - gTSSs[cpu].ESP0 = nextthread->KernelStack-4; - __asm__ __volatile__("mov %0, %%db0\n\t" : : "r"(nextthread) ); + // Update CPU state + gaCPUs[cpu].Current = nextthread; + gaCPUs[cpu].LastTimerThread = NULL; + 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(); - } + // 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 - ); + 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 ; + + SHORTREL(&glThreadListLock); } /** - * \fn void Proc_Scheduler(int CPU) - * \brief Swap current thread and clears dead threads + * \brief Handle the per-CPU timer ticking + */ -void Proc_Scheduler(int CPU) +void Proc_HandleEventTimer(int CPU) { - #if USE_MP - if( GetCPUNum() ) - gpMP_LocalAPIC->EOI.Val = 0; - else - #endif - outb(0x20, 0x20); - __asm__ __volatile__ ("sti"); - // Call the timer update code Timer_CallTimers(); @@ -857,6 +860,8 @@ void Proc_Scheduler(int CPU) // If two ticks happen within the same task, and it's not an idle task, swap if( gaCPUs[CPU].Current->TID > giNumCPUs && gaCPUs[CPU].Current == gaCPUs[CPU].LastTimerThread ) { + const tThread* const t = gaCPUs[CPU].Current; + LOG("Preempting thread %p(%i %s)", t, t->TID, t->ThreadName); Proc_Reschedule(); } diff --git a/KernelLand/Kernel/arch/x86/vm8086.c b/KernelLand/Kernel/arch/x86/vm8086.c index 93ea63ae..f1b50059 100644 --- a/KernelLand/Kernel/arch/x86/vm8086.c +++ b/KernelLand/Kernel/arch/x86/vm8086.c @@ -68,16 +68,14 @@ Uint32 gaVM8086_MemBitmap[VM8086_BLOCKCOUNT/32]; // === FUNCTIONS === int VM8086_Install(char **Arguments) { - tPID pid; - Semaphore_Init(&gVM8086_TasksToDo, 0, 10, "VM8086", "TasksToDo"); // Lock to avoid race conditions Mutex_Acquire( &glVM8086_Process ); // Create BIOS Call process - pid = Proc_Clone(CLONE_VM); - //Log_Debug("VM8086", "pid = %i", pid); + tPID pid = Proc_Clone(CLONE_VM); + LOG("pid = %i", pid); if(pid == -1) { Log_Error("VM8086", "Unable to clone kernel into VM8086 worker"); @@ -87,15 +85,14 @@ int VM8086_Install(char **Arguments) { Uint * volatile stacksetup; // Initialising Stack Uint16 * volatile rmstack; // Real Mode Stack - int i; - //Log_Debug("VM8086", "Initialising worker"); + LOG("Initialising worker"); // Set Image Name Threads_SetName("VM8086"); // Map ROM Area - for(i=0xA0;i<0x100;i++) { + for(unsigned int i = 0xA0;i<0x100;i++) { MM_RefPhys(i * 0x1000); MM_Map( (void*)(i * 0x1000), i * 0x1000 ); } @@ -150,6 +147,7 @@ int VM8086_Install(char **Arguments) stacksetup--; *stacksetup = 0x20|3; // ES - Kernel stacksetup--; *stacksetup = 0x20|3; // FS stacksetup--; *stacksetup = 0x20|3; // GS + LOG("stacksetup = %p, entering vm8086"); __asm__ __volatile__ ( "mov %%eax,%%esp;\n\t" // Set stack pointer "pop %%gs;\n\t" @@ -164,6 +162,7 @@ int VM8086_Install(char **Arguments) gVM8086_WorkerPID = pid; // It's released when the GPF fires + LOG("Waiting for worker %i to start", gVM8086_WorkerPID); Mutex_Acquire( &glVM8086_Process ); Mutex_Release( &glVM8086_Process ); diff --git a/KernelLand/Kernel/events.c b/KernelLand/Kernel/events.c index ec47a169..a572d433 100644 --- a/KernelLand/Kernel/events.c +++ b/KernelLand/Kernel/events.c @@ -87,7 +87,7 @@ Uint32 Threads_WaitEvents(Uint32 EventMask) { Threads_int_Sleep(THREAD_STAT_EVENTSLEEP, NULL, EventMask, &us, NULL, &us->IsLocked); - // Woken when lock is acquired + // Woken when an event fires SHORTLOCK( &us->IsLocked ); } diff --git a/KernelLand/Kernel/threads.c b/KernelLand/Kernel/threads.c index 80b27966..469c5ec1 100644 --- a/KernelLand/Kernel/threads.c +++ b/KernelLand/Kernel/threads.c @@ -4,6 +4,7 @@ * threads.c * - Common Thread Control */ +#define DEBUG 0 #include #include #include @@ -329,11 +330,10 @@ void Threads_SetPriority(tThread *Thread, int Pri) */ tThread *Threads_CloneTCB(Uint Flags) { - tThread *cur, *new; - cur = Proc_GetCurThread(); + tThread *cur = Proc_GetCurThread(); // Allocate and duplicate - new = malloc(sizeof(tThread)); + tThread *new = malloc(sizeof(tThread)); if(new == NULL) { errno = -ENOMEM; return NULL; } memcpy(new, cur, sizeof(tThread)); @@ -760,6 +760,7 @@ void Threads_Yield(void) void Threads_int_WaitForStatusEnd(enum eThreadStatus Status) { tThread *us = Proc_GetCurThread(); + LOG("us = %p(%i %s), status=%i", us, us->TID, us->ThreadName, Status); ASSERT(Status != THREAD_STAT_ACTIVE); ASSERT(Status != THREAD_STAT_DEAD); while( us->Status == Status ) @@ -1472,6 +1473,7 @@ tThread *Threads_int_GetRunnable(void) // Single-list round-robin // ----------------------------------- tThread *thread = gActiveThreads.Head; + LOG("thread = %p", thread); if( thread ) { gActiveThreads.Head = thread->Next; @@ -1493,23 +1495,20 @@ tThread *Threads_int_GetRunnable(void) */ tThread *Threads_GetNextToRun(int CPU, tThread *Last) { - // If this CPU has the lock, we must let it complete - if( CPU_HAS_LOCK( &glThreadListLock ) ) - return Last; + ASSERT( CPU_HAS_LOCK(&glThreadListLock) ); // Don't change threads if the current CPU has switches disabled - if( gaThreads_NoTaskSwitch[CPU] ) + if( gaThreads_NoTaskSwitch[CPU] ) { + LOG("- Denied"); return Last; - - // Lock thread list - SHORTLOCK( &glThreadListLock ); + } // Make sure the current (well, old) thread is marked as de-scheduled if(Last) Last->CurCPU = -1; // No active threads, just take a nap if(giNumActiveThreads == 0) { - SHORTREL( &glThreadListLock ); + LOG("- No active"); #if DEBUG_TRACE_TICKETS Log("No active threads"); #endif @@ -1552,7 +1551,7 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last) // Call actual scheduler tThread *thread = Threads_int_GetRunnable(); - + // Anything to do? if( thread ) { @@ -1578,8 +1577,6 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last) Warning("No runnable thread for CPU%i", CPU); } - SHORTREL( &glThreadListLock ); - return thread; } diff --git a/KernelLand/Kernel/time.c b/KernelLand/Kernel/time.c index 15b61907..478c41f3 100644 --- a/KernelLand/Kernel/time.c +++ b/KernelLand/Kernel/time.c @@ -76,8 +76,9 @@ void Timer_CallTimers() { // Tick the random number generator every time timers are checked rand(); - + SHORTLOCK(&gTimers_ListLock); + LOG("gTimers = %p (%lli ms)", gTimers, (gTimers ? gTimers->FiresAfter : 0)); while( gTimers && gTimers->FiresAfter < now() ) { ASSERT( gTimers != gTimers->Next );