// === IMPORTS ===
extern void ArchThreads_Init();
+extern void Proc_Start();
extern tThread *Proc_GetCurThread();
extern int Proc_Clone(Uint *Err, Uint Flags);
void Threads_SetTickets(int Num);
int Threads_WaitTID(int TID, int *status);
tThread *Threads_GetThread(Uint TID);
+void Threads_AddToDelete(tThread *Thread);
tThread *Threads_int_GetPrev(tThread **List, tThread *Thread);
void Threads_Exit(int TID, int Status);
void Threads_Kill(tThread *Thread, int Status);
void Threads_Yield();
void Threads_Sleep();
void Threads_Wake(tThread *Thread);
+void Threads_AddActive(tThread *Thread);
int Threads_GetPID();
int Threads_GetTID();
int Threads_GetUID();
cur->ThreadName = "Idle Thread";
Threads_SetTickets(0); // Never called randomly
cur->Quantum = 1; // 1 slice quantum
- for(;;) __asm__ __volatile__ ("hlt"); // Just yeilds
+ HALT();
+ for(;;) {
+ HALT(); // Just yeilds
+ }
}
#endif
+
+ Proc_Start();
}
/**
* \brief Wait for a task to change state
*/
int Threads_WaitTID(int TID, int *status)
-{
+{
// Any Child
if(TID == -1) {
{
case THREAD_STAT_ZOMBIE:
t->Status = THREAD_STAT_DEAD;
- *status = 0;
+ if(status) *status = 0;
+ Threads_AddToDelete( t );
break;
default:
- *status = -1;
+ if(status) *status = -1;
break;
}
return ret;
return NULL;
}
+/**
+ * \fn void Threads_AddToDelete(tThread *Thread)
+ * \brief Adds a thread to the delete queue
+ */
+void Threads_AddToDelete(tThread *Thread)
+{
+ // Add to delete queue
+ if(gDeleteThreads) {
+ Thread->Next = gDeleteThreads;
+ gDeleteThreads = Thread;
+ } else {
+ Thread->Next = NULL;
+ gDeleteThreads = Thread;
+ }
+}
+
/**
* \fn tThread *Threads_int_GetPrev(tThread *List, tThread *Thread)
* \brief Gets the previous entry in a thead linked list
*/
void Threads_Exit(int TID, int Status)
{
- Threads_Kill( Proc_GetCurThread(), (Uint)Status & 0xFF );
+ if( TID == 0 )
+ Threads_Kill( Proc_GetCurThread(), (Uint)Status & 0xFF );
+ else
+ Threads_Kill( Threads_GetThread(TID), (Uint)Status & 0xFF );
}
/**
tMsg *msg;
// Kill all children
- #if 0
+ #if 1
{
tThread *child;
for(child = gActiveThreads;
child;
child = child->Next)
{
- if(child->PTID == gCurrentThread->TID)
+ if(child->PTID == Thread->TID)
Threads_Kill(child, -1);
}
}
if(Status == -1)
{
Thread->Status = THREAD_STAT_DEAD;
- // Add to delete queue
- if(gDeleteThreads) {
- Thread->Next = gDeleteThreads;
- gDeleteThreads = Thread;
- } else {
- Thread->Next = NULL;
- gDeleteThreads = Thread;
- }
+ Threads_AddToDelete( Thread );
} else {
Thread->Status = THREAD_STAT_ZOMBIE;
}
*/
void Threads_Yield()
{
- Proc_GetCurThread()->Quantum = 0;
+ Proc_GetCurThread()->Remaining = 0;
HALT();
}
tThread *cur = Proc_GetCurThread();
tThread *thread;
- //Log("Proc_Sleep: %i going to sleep", gCurrentThread->TID);
+ Log("Proc_Sleep: %i going to sleep", cur->TID);
// Acquire Spinlock
LOCK( &giThreadListLock );
}
}
+/**
+ * \fn void Threads_AddActive(tThread *Thread)
+ * \brief Adds a thread to the active queue
+ */
+void Threads_AddActive(tThread *Thread)
+{
+ LOCK( &giThreadListLock );
+ Thread->Next = gActiveThreads;
+ gActiveThreads = Thread;
+ giNumActiveThreads ++;
+ giTotalTickets += Thread->NumTickets;
+ //Log("Threads_AddActive: giNumActiveThreads = %i, giTotalTickets = %i",
+ // giNumActiveThreads, giTotalTickets);
+ RELEASE( &giThreadListLock );
+}
+
#if 0
/**
* \fn void Threads_SetSignalHandler(int Num, void *Handler)
/**
* \fn void Threads_SendSignal(int TID, int Num)
+ * \brief Send a signal to a thread
*/
void Threads_SendSignal(int TID, int Num)
{
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)
{
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 );
+ Threads_Kill( Proc_GetCurThread(), 0 );
+}