-/**
- * \fn void Proc_Exit()
- * \brief Kill the current process
- */
-void Proc_Exit()
-{
- tThread *thread;
- tMsg *msg;
-
- ///\note Double lock is needed due to overlap of locks
-
- // Lock thread (stop us recieving messages)
- LOCK( &gCurrentThread->IsLocked );
-
- // Lock thread list
- LOCK( &giThreadListLock );
-
- // Get previous thread on list
- thread = Proc_int_GetPrevThread( &gActiveThreads, gCurrentThread );
- if(!thread) {
- Warning("Proc_Exit - Current thread is not on the active queue");
- return;
- }
-
- // Clear Message Queue
- while( gCurrentThread->Messages )
- {
- msg = gCurrentThread->Messages->Next;
- free( gCurrentThread->Messages );
- gCurrentThread->Messages = msg;
- }
-
- gCurrentThread->Remaining = 0; // Clear Remaining Quantum
- gCurrentThread->Quantum = 0; // Clear Quantum to indicate dead thread
- thread->Next = gCurrentThread->Next; // Remove from active
-
- // Add to delete queue
- if(gDeleteThreads) {
- gCurrentThread->Next = gDeleteThreads;
- gDeleteThreads = gCurrentThread;
- } else {
- gCurrentThread->Next = NULL;
- gDeleteThreads = gCurrentThread;
- }
-
- giNumActiveThreads --;
- giTotalTickets -= gCurrentThread->NumTickets;
-
- // Mark thread as sleeping
- gCurrentThread->Status = THREAD_STAT_DEAD;
-
- // Release spinlocks
- RELEASE( &gCurrentThread->IsLocked ); // Released first so that it IS released
- RELEASE( &giThreadListLock );
- __asm__ __volatile__ ("hlt");
-}
-
-/**
- * \fn void Proc_Yield()
- * \brief Yield remainder of timeslice
- */
-void Proc_Yield()
-{
- gCurrentThread->Quantum = 0;
- __asm__ __volatile__ ("hlt");
-}
-
-/**
- * \fn void Proc_Sleep()
- * \brief Take the current process off the run queue
- */
-void Proc_Sleep()
-{
- tThread *thread;
-
- //Log("Proc_Sleep: %i going to sleep", gCurrentThread->TID);
-
- // Acquire Spinlock
- LOCK( &giThreadListLock );
-
- // Get thread before current thread
- thread = Proc_int_GetPrevThread( &gActiveThreads, gCurrentThread );
- if(!thread) {
- Warning("Proc_Sleep - Current thread is not on the active queue");
- return;
- }
-
- // Don't sleep if there is a message waiting
- if( gCurrentThread->Messages ) {
- RELEASE( &giThreadListLock );
- return;
- }
-
- // Unset remaining timeslices (force a task switch on timer fire)
- gCurrentThread->Remaining = 0;
-
- // Remove from active list
- thread->Next = gCurrentThread->Next;
-
- // Add to Sleeping List (at the top)
- gCurrentThread->Next = gSleepingThreads;
- gSleepingThreads = gCurrentThread;
-
- // Reduce the active count & ticket count
- giNumActiveThreads --;
- giTotalTickets -= gCurrentThread->NumTickets;
-
- // Mark thread as sleeping
- gCurrentThread->Status = THREAD_STAT_SLEEPING;
-
- // Release Spinlock
- RELEASE( &giThreadListLock );
-
- __asm__ __volatile__ ("hlt");
-}
-
-/**
- * \fn void Thread_Wake( tThread *Thread )
- * \brief Wakes a sleeping/waiting thread up
- */
-void Thread_Wake(tThread *Thread)
-{
- tThread *prev;
- switch(Thread->Status)
- {
- case THREAD_STAT_ACTIVE: break;
- case THREAD_STAT_SLEEPING:
- LOCK( &giThreadListLock );
- prev = Proc_int_GetPrevThread(&gSleepingThreads, Thread);
- prev->Next = Thread->Next; // Remove from sleeping queue
- Thread->Next = gActiveThreads; // Add to active queue
- gActiveThreads = Thread;
- Thread->Status = THREAD_STAT_ACTIVE;
- RELEASE( &giThreadListLock );
- break;
- case THREAD_STAT_WAITING:
- Warning("Thread_Wake - Waiting threads are not currently supported");
- break;
- case THREAD_STAT_DEAD:
- Warning("Thread_Wake - Attempt to wake dead thread (%i)", Thread->TID);
- break;
- default:
- Warning("Thread_Wake - Unknown process status (%i)\n", Thread->Status);
- break;
- }
-}
-