Bugfixed MP scheduling code in MP build
authorJohn Hodge <[email protected]>
Wed, 28 Jul 2010 14:47:23 +0000 (22:47 +0800)
committerJohn Hodge <[email protected]>
Wed, 28 Jul 2010 14:47:23 +0000 (22:47 +0800)
Kernel/arch/x86/proc.c
Kernel/threads.c

index 0433121..bee311a 100644 (file)
@@ -29,6 +29,7 @@ typedef struct sCPU
        Uint8   State;  // 0: Unavaliable, 1: Idle, 2: Active
        Uint16  Resvd;
        tThread *Current;
+       tThread *IdleThread;
 }      tCPU;
 #endif
 
@@ -427,23 +428,51 @@ void Proc_Start(void)
         int    i;
        #endif
        
-       // Start Interrupts (and hence scheduler)
-       __asm__ __volatile__("sti");
-       
        #if USE_MP
        // Start APs
        for( i = 0; i < giNumCPUs; i ++ )
        {
+               // Create Idle Task
+               if(Proc_Clone(0, 0) == 0)
+               {
+                       gaCPUs[i].IdleThread = Proc_GetCurThread();
+                       gaCPUs[i].IdleThread->ThreadName = "Idle Thread";
+                       gaCPUs[i].IdleThread->NumTickets = 0;   // Never called randomly
+                       gaCPUs[i].IdleThread->Quantum = 1;      // 1 slice quantum
+                       for(;;) HALT(); // Just yeilds
+               }
                gaCPUs[i].Current = NULL;
+               
+               // Start the AP
                if( i != giProc_BootProcessorID ) {
                        MP_StartAP( i );
                }
        }
        
+       // BSP still should run the current task
+       gaCPUs[0].Current = &gThreadZero;
+       
+       // Start interrupts and wait for APs to come up
        Log("Waiting for APs to come up\n");
-       //__asm__ __volatile__ ("sti");
+       __asm__ __volatile__ ("sti");
        while( giNumInitingCPUs )       __asm__ __volatile__ ("hlt");
        MM_FinishVirtualInit();
+       #else
+       // Create Idle Task
+       if(Proc_Clone(0, 0) == 0)
+       {
+               tThread *cur = Proc_GetCurThread();
+               cur->ThreadName = "Idle Thread";
+               Threads_SetTickets(0);  // Never called randomly
+               cur->Quantum = 1;       // 1 slice quantum
+               for(;;) HALT(); // Just yeilds
+       }
+       
+       // Set current task
+       gCurrentThread = &gThreadZero;
+       
+       // Start Interrupts (and hence scheduler)
+       __asm__ __volatile__("sti");
        #endif
 }
 
@@ -829,29 +858,33 @@ void Proc_Scheduler(int CPU)
        thread = gCurrentThread;
        #endif
        
-       // Reduce remaining quantum and continue timeslice if non-zero
-       if(thread->Remaining--) return;
-       // Reset quantum for next call
-       thread->Remaining = thread->Quantum;
-       
-       // Get machine state
-       __asm__ __volatile__ ("mov %%esp, %0":"=r"(esp));
-       __asm__ __volatile__ ("mov %%ebp, %0":"=r"(ebp));
-       eip = GetEIP();
-       if(eip == SWITCH_MAGIC) return; // Check if a switch happened
-       
-       // Save machine state
-       thread->SavedState.ESP = esp;
-       thread->SavedState.EBP = ebp;
-       thread->SavedState.EIP = eip;
+       if( thread )
+       {
+               // Reduce remaining quantum and continue timeslice if non-zero
+               if(thread->Remaining--) return;
+               // Reset quantum for next call
+               thread->Remaining = thread->Quantum;
+               
+               // Get machine state
+               __asm__ __volatile__ ("mov %%esp, %0":"=r"(esp));
+               __asm__ __volatile__ ("mov %%ebp, %0":"=r"(ebp));
+               eip = GetEIP();
+               if(eip == SWITCH_MAGIC) return; // Check if a switch happened
+               
+               // Save machine state
+               thread->SavedState.ESP = esp;
+               thread->SavedState.EBP = ebp;
+               thread->SavedState.EIP = eip;
+       }
        
        // Get next thread to run
        thread = Threads_GetNextToRun(CPU, thread);
        
-       // Error Check
+       // No avaliable tasks, just go into low power mode
        if(thread == NULL) {
-               Warning("Hmm... Threads_GetNextToRun returned NULL, I don't think this should happen.\n");
-               return;
+               //HALT();
+               //return;
+               thread = gaCPUs[CPU].IdleThread;
        }
        
        #if DEBUG_TRACE_SWITCH
@@ -864,9 +897,7 @@ void Proc_Scheduler(int CPU)
        
        // Set current thread
        #if USE_MP
-       gaCPUs[CPU].Current->bIsRunning = 0;
        gaCPUs[CPU].Current = thread;
-       thread->bIsRunning = 1;
        #else
        gCurrentThread = thread;
        #endif
index 58100b6..53756ed 100644 (file)
@@ -52,24 +52,10 @@ void        Threads_Dump(void);
 // -- Core Thread --
 // Only used for the core kernel
 tThread        gThreadZero = {
-       NULL, 0,        // Next, Lock
-       THREAD_STAT_ACTIVE,     // Status
-       0,      // Exit Status
-       0, 0,   // TID, TGID
-       0, 0,   // UID, GID
-       0,      // Parent Thread ID
-       "ThreadZero",   // Name
-       
-       0,      // Kernel Stack
-       {0},    // Saved State
-       {0},    // VM State
-       
-       0, 0,   // Current Fault, Fault Handler
-       
-       NULL, NULL,     // Messages, Last Message
-       DEFAULT_QUANTUM, DEFAULT_QUANTUM,       // Quantum, Remaining
-       DEFAULT_TICKETS,
-       {0}     // Default config to zero
+       Status: THREAD_STAT_ACTIVE,     // Status
+       ThreadName:     "ThreadZero",   // Name
+       Quantum: DEFAULT_QUANTUM, Remaining:    DEFAULT_QUANTUM,        // Quantum, Remaining
+       NumTickets:     DEFAULT_TICKETS
        };
 // -- Processes --
 // --- Locks ---
@@ -98,19 +84,7 @@ void Threads_Init(void)
        gActiveThreads = &gThreadZero;
        //giFreeTickets = gThreadZero.NumTickets;
        giNumActiveThreads = 1;
-       
-       #if 1
-       // Create Idle Task
-       if(Proc_Clone(0, 0) == 0)
-       {
-               tThread *cur = Proc_GetCurThread();
-               cur->ThreadName = "Idle Thread";
-               Threads_SetTickets(0);  // Never called randomly
-               cur->Quantum = 1;       // 1 slice quantum
-               for(;;) HALT(); // Just yeilds
-       }
-       #endif
-       
+               
        Proc_Start();
 }
 
@@ -121,11 +95,13 @@ void Threads_Init(void)
 int Threads_SetName(char *NewName)
 {
        tThread *cur = Proc_GetCurThread();
-       if( IsHeap(cur->ThreadName) )
-               free( cur->ThreadName );
-       // TODO: Possible concurrency issue
-       cur->ThreadName = malloc(strlen(NewName)+1);
-       strcpy(cur->ThreadName, NewName);
+       char    *oldname = cur->ThreadName;
+       
+       cur->ThreadName = NULL;
+       
+       if( IsHeap(oldname) )   free( oldname );
+       
+       cur->ThreadName = strdup(NewName);
        return 0;
 }
 
@@ -182,6 +158,7 @@ tThread *Threads_CloneTCB(Uint *Err, Uint Flags)
        new->PTID = cur->TID;
        
        // Clone Name
+       Log("Threads_CloneTCB: cur (%p) ->ThreadName = %p", cur, cur->ThreadName);
        new->ThreadName = strdup(cur->ThreadName);
        
        // Set Thread Group ID (PID)
@@ -736,7 +713,13 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
                        giFreeTickets += Last->NumTickets;
                Last->CurCPU = -1;
        }
-
+       
+       // No free tickets (all tasks delegated to cores)
+       if( giFreeTickets == 0 ) {
+               RELEASE(&glThreadListLock);
+               return NULL;
+       }
+       
        // Get the ticket number
        ticket = number = rand() % giFreeTickets;
        

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