+
+/**
+ * \fn tThread *Threads_GetNextToRun(int CPU)
+ * \brief Gets the next thread to run
+ */
+tThread *Threads_GetNextToRun(int CPU)
+{
+ tThread *thread;
+ int ticket;
+ int number;
+
+ if(giNumActiveThreads == 0) {
+ //Log_Debug("Threads", "CPU%i has no threads to run", CPU);
+ return NULL;
+ }
+
+ // Special case: 1 thread
+ if(giNumActiveThreads == 1) {
+ //Log_Debug("Threads", "CPU%i has only one thread %i %s",
+ // CPU, gActiveThreads->TID, gActiveThreads->ThreadName);
+ return gActiveThreads;
+ }
+
+ //Log(" Threads_GetNextToRun: giNumActiveThreads=%i,giTotalTickets=%i",
+ // giNumActiveThreads, giTotalTickets);
+ // Get the ticket number
+ ticket = number = rand() % giTotalTickets;
+
+ //Log(" Threads_GetNextToRun: ticket = %i", ticket);
+
+ // Find the next thread
+ for(thread=gActiveThreads;thread;thread=thread->Next)
+ {
+ if(thread->NumTickets > number) break;
+ number -= thread->NumTickets;
+ }
+
+ // Error Check
+ if(thread == NULL)
+ {
+ number = 0;
+ for(thread=gActiveThreads;thread;thread=thread->Next)
+ number += thread->NumTickets;
+ Panic("Bookeeping Failed - giTotalTicketCount (%i) != true count (%i)",
+ giTotalTickets, number);
+ }
+
+ //Log_Debug("Threads", "Switching CPU%i to %p (%s)",
+ // CPU, thread, thread->ThreadName);
+
+ return thread;
+}
+
+/**
+ * \fn void Threads_SegFault(tVAddr Addr)
+ * \brief Called when a Segment Fault occurs
+ */
+void Threads_SegFault(tVAddr Addr)
+{
+ //Threads_SendSignal( Proc_GetCurThread()->TID, SIGSEGV );
+ Warning("Thread #%i committed a segfault at address %p", Proc_GetCurThread()->TID, Addr);
+ Threads_Exit( 0, -1 );
+}
+
+// === EXPORTS ===
+EXPORT(Threads_GetUID);