Kernel/x86 - Clean up some of the task switching code (possibly a little broken)
authorJohn Hodge <[email protected]>
Sun, 8 Feb 2015 05:57:42 +0000 (13:57 +0800)
committerJohn Hodge <[email protected]>
Sun, 8 Feb 2015 05:57:42 +0000 (13:57 +0800)
KernelLand/Kernel/arch/x86/common.inc.asm [new file with mode: 0644]
KernelLand/Kernel/arch/x86/desctab.asm
KernelLand/Kernel/arch/x86/proc.asm
KernelLand/Kernel/arch/x86/proc.c
KernelLand/Kernel/arch/x86/vm8086.c
KernelLand/Kernel/events.c
KernelLand/Kernel/threads.c
KernelLand/Kernel/time.c

diff --git a/KernelLand/Kernel/arch/x86/common.inc.asm b/KernelLand/Kernel/arch/x86/common.inc.asm
new file mode 100644 (file)
index 0000000..ec7f844
--- /dev/null
@@ -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
index 354a001..3382534 100644 (file)
@@ -1,6 +1,7 @@
 ; AcessOS Microkernel Version
 ;
 ; desctab.asm
 ; AcessOS Microkernel Version
 ;
 ; desctab.asm
+%include "arch/x86/common.inc.asm"
 [BITS 32]
 
 
 [BITS 32]
 
 
@@ -182,14 +183,14 @@ Isr0xED:
        jmp .jmp
 
 [global Isr0xEE]
        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
 ; 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:
 ; Spurious Interrupt
 [global Isr0xEF]
 Isr0xEF:
@@ -201,7 +202,7 @@ Isr0xEF:
 ; - Timer
 [global Isr240]
 [global Isr240.jmp]
 ; - Timer
 [global Isr240]
 [global Isr240.jmp]
-[extern SchedulerBase]
+[extern Proc_EventTimer_PIT]
 [extern SetAPICTimerCount]
 Isr240:
        push 0  ; Line up with Argument in errors
 [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
        %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
        %endif
 ; - Assignable
 %assign i      0xF1
@@ -254,11 +255,8 @@ ErrorCommon:
 ; --------------------------
 [extern SyscallHandler]
 SyscallCommon:
 ; --------------------------
 [extern SyscallHandler]
 SyscallCommon:
-       pusha
-       push ds
-       push es
-       push fs
-       push gs
+       PUSH_CC ; Actually a pusha
+       PUSH_SEG
        
        push esp
        call SyscallHandler
        
        push esp
        call SyscallHandler
@@ -286,17 +284,8 @@ SyscallCommon:
 [global IRQCommon_handled]
 IRQCommon_handled equ IRQCommon.handled
 IRQCommon:
 [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
        
        push esp
        call IRQ_Handler
index be4c10d..1987166 100644 (file)
@@ -1,5 +1,6 @@
 ; AcessOS Microkernel Version
 ; Start.asm
 ; AcessOS Microkernel Version
 ; Start.asm
+%include "arch/x86/common.inc.asm"
 
 [bits 32]
 
 
 [bits 32]
 
@@ -11,19 +12,6 @@ KSTACK_USERSTATE_SIZE        equ     (4+8+1+5)*4     ; SRegs, GPRegs, CPU, IRET
 
 [section .text]
 
 
 [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:
 [extern MM_Clone]
 [global Proc_CloneInt]
 Proc_CloneInt:
@@ -53,7 +41,7 @@ Proc_CloneInt:
 ; +16 = Old RIP save loc
 ; +20 = CR3
 SwitchTasks:
 ; +16 = Old RIP save loc
 ; +20 = CR3
 SwitchTasks:
-       pusha
+       PUSH_CC
        
        ; Old IP
        mov eax, [esp+0x20+16]
        
        ; Old IP
        mov eax, [esp+0x20+16]
@@ -78,7 +66,7 @@ SwitchTasks:
        jmp ecx
 
 .restore:
        jmp ecx
 
 .restore:
-       popa
+       POP_CC
        xor eax, eax
        ret
 
        xor eax, eax
        ret
 
@@ -122,17 +110,8 @@ Proc_RestoreSSE:
 [extern Isr240.jmp]
 [global SetAPICTimerCount]
 SetAPICTimerCount:
 [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]
        
        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 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
 
        sub eax, Isr240.jmp+5
        mov DWORD [Isr240.jmp+1], eax
 
@@ -160,72 +139,55 @@ SetAPICTimerCount:
 .ret:
        mov dx, 0x20
        mov al, 0x20
 .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
        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
        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
        
        %if USE_MP
        call GetCPUNum
-       mov ebx, eax
        push eax        ; Push as argument
        %else
        push 0
        %endif
        
        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
 [global scheduler_return]
 scheduler_return:      ; Used by some hackery in Proc_DumpThreadCPUState
-       
        add esp, 4      ; Remove CPU Number (thread is poped later)
 
        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
 
 ;
        jmp ReturnFromInterrupt
 
 ;
index 999ac67..b1dcb99 100644 (file)
@@ -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 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[];
 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);
 //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);
 // 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_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 ---
 
 // === 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
        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__ ("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)
 {
 
 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
        if(!newThread)  return -1;
        
        // Create new KStack
@@ -445,12 +444,14 @@ tTID Proc_NewKThread(void (*Fcn)(void*), void *Data)
                free(newThread);
                return -1;
        }
                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) = (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)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;
        
        newThread->SavedState.ESP = esp;
        newThread->SavedState.EIP = (Uint)&NewTaskHeader;
@@ -463,13 +464,16 @@ tTID Proc_NewKThread(void (*Fcn)(void*), void *Data)
        return newThread->TID;
 }
 
        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)
 
 /**
  * \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)
 {
  */
 tPID Proc_Clone(Uint Flags)
 {
-       tThread *newThread;
        tThread *cur = Proc_GetCurThread();
        tThread *cur = Proc_GetCurThread();
-       Uint    eip;
 
        // Sanity, please
        if( !(Flags & CLONE_VM) ) {
 
        // Sanity, please
        if( !(Flags & CLONE_VM) ) {
@@ -488,17 +490,17 @@ tPID Proc_Clone(Uint Flags)
        }
        
        // New thread
        }
        
        // New thread
-       newThread = Threads_CloneTCB(Flags);
+       tThread *newThread = Threads_CloneTCB(Flags);
        if(!newThread)  return -1;
        ASSERT(newThread->Process);
        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
 
        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 ) {
        if( eip == 0 ) {
+               SHORTREL( &glThreadListLock );
+               LOG("In new thread");
                return 0;
        }
        //ASSERT(newThread->Process);
                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;
        }
                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;
 
        // 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));
        
        // 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)
 {
 
 void Proc_Reschedule(void)
 {
-       tThread *nextthread, *curthread;
         int    cpu = GetCPUNum();
 
        // TODO: Wait for the lock?
         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();
 
        // 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 )
        {
        // 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();
        }
        
                Proc_Reschedule();
        }
        
index 93ea63a..f1b5005 100644 (file)
@@ -68,16 +68,14 @@ Uint32      gaVM8086_MemBitmap[VM8086_BLOCKCOUNT/32];
 // === FUNCTIONS ===
 int VM8086_Install(char **Arguments)
 {
 // === 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
        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");
        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
        {
                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
        
                // 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 );
                }
                        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
                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"
                __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
        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 );
        
        Mutex_Acquire( &glVM8086_Process );
        Mutex_Release( &glVM8086_Process );
        
index ec47a16..a572d43 100644 (file)
@@ -87,7 +87,7 @@ Uint32 Threads_WaitEvents(Uint32 EventMask)
        {
                Threads_int_Sleep(THREAD_STAT_EVENTSLEEP, NULL, EventMask,
                        &us, NULL, &us->IsLocked);
        {
                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 );
        }
        
                SHORTLOCK( &us->IsLocked );
        }
        
index 80b2796..469c5ec 100644 (file)
@@ -4,6 +4,7 @@
  * threads.c
  * - Common Thread Control
  */
  * threads.c
  * - Common Thread Control
  */
+#define DEBUG  0
 #include <acess.h>
 #include <threads.h>
 #include <threads_int.h>
 #include <acess.h>
 #include <threads.h>
 #include <threads_int.h>
@@ -329,11 +330,10 @@ void Threads_SetPriority(tThread *Thread, int Pri)
  */
 tThread *Threads_CloneTCB(Uint Flags)
 {
  */
 tThread *Threads_CloneTCB(Uint Flags)
 {
-       tThread *cur, *new;
-       cur = Proc_GetCurThread();
+       tThread *cur = Proc_GetCurThread();
        
        // Allocate and duplicate
        
        // Allocate and duplicate
-       new = malloc(sizeof(tThread));
+       tThread *new = malloc(sizeof(tThread));
        if(new == NULL) { errno = -ENOMEM; return NULL; }
        memcpy(new, cur, 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();
 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 )
        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;
        // Single-list round-robin
        // -----------------------------------
        tThread *thread = gActiveThreads.Head;
+       LOG("thread = %p", thread);
        if( thread )
        {
                gActiveThreads.Head = thread->Next;
        if( thread )
        {
                gActiveThreads.Head = thread->Next;
@@ -1493,23 +1495,20 @@ tThread *Threads_int_GetRunnable(void)
  */
 tThread *Threads_GetNextToRun(int CPU, tThread *Last)
 {
  */
 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
        
        // Don't change threads if the current CPU has switches disabled
-       if( gaThreads_NoTaskSwitch[CPU] )
+       if( gaThreads_NoTaskSwitch[CPU] ) {
+               LOG("- Denied");
                return Last;
                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) {
        
        // 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
                #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();
 
        // Call actual scheduler        
        tThread *thread = Threads_int_GetRunnable();
-               
+       
        // Anything to do?
        if( thread )
        {
        // Anything to do?
        if( thread )
        {
@@ -1578,8 +1577,6 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
                Warning("No runnable thread for CPU%i", CPU);
        }
        
                Warning("No runnable thread for CPU%i", CPU);
        }
        
-       SHORTREL( &glThreadListLock );
-       
        return thread;
 }
 
        return thread;
 }
 
index 15b6190..478c41f 100644 (file)
@@ -76,8 +76,9 @@ void Timer_CallTimers()
 {
        // Tick the random number generator every time timers are checked
        rand();
 {
        // Tick the random number generator every time timers are checked
        rand();
-       
+
        SHORTLOCK(&gTimers_ListLock);
        SHORTLOCK(&gTimers_ListLock);
+       LOG("gTimers = %p (%lli ms)", gTimers, (gTimers ? gTimers->FiresAfter : 0));
        while( gTimers && gTimers->FiresAfter < now() )
        {
                ASSERT( gTimers != gTimers->Next );     
        while( gTimers && gTimers->FiresAfter < now() )
        {
                ASSERT( gTimers != gTimers->Next );     

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