-/**
- * \fn void Threads_SegFault(tVAddr Addr)
- * \brief Called when a Segment Fault occurs
- */
-void Threads_SegFault(tVAddr Addr)
-{
- Warning("Thread #%i committed a segfault at address %p", Proc_GetCurThread()->TID, Addr);
- Threads_Fault( 1 );
- //Threads_Exit( 0, -1 );
-}
-
-/**
- * \brief Acquire a heavy mutex
- * \param Mutex Mutex to acquire
- *
- * This type of mutex checks if the mutex is avaliable, and acquires it
- * if it is. Otherwise, the current thread is added to the mutex's wait
- * queue and the thread suspends. When the holder of the mutex completes,
- * the oldest thread (top thread) on the queue is given the lock and
- * restarted.
- */
-void Mutex_Acquire(tMutex *Mutex)
-{
- tThread *us = Proc_GetCurThread();
-
- // Get protector
- SHORTLOCK( &Mutex->Protector );
-
- //Log("Mutex_Acquire: (%p)", Mutex);
-
- // Check if the lock is already held
- if( Mutex->Owner ) {
- SHORTLOCK( &glThreadListLock );
- // - Remove from active list
- us = Threads_RemActive();
- us->Next = NULL;
- // - Mark as sleeping
- us->Status = THREAD_STAT_MUTEXSLEEP;
- us->WaitPointer = Mutex;
-
- // - Add to waiting
- if(Mutex->LastWaiting) {
- Mutex->LastWaiting->Next = us;
- Mutex->LastWaiting = us;
- }
- else {
- Mutex->Waiting = us;
- Mutex->LastWaiting = us;
- }
- #if 0
- {
- int i = 0;
- tThread *t;
- for( t = Mutex->Waiting; t; t = t->Next, i++ )
- Log("[%i] (tMutex)%p->Waiting[%i] = %p (%i %s)", us->TID, Mutex, i,
- t, t->TID, t->ThreadName);
- }
- #endif
-
- SHORTREL( &glThreadListLock );
- SHORTREL( &Mutex->Protector );
- while(us->Status == THREAD_STAT_MUTEXSLEEP) Threads_Yield();
- // We're only woken when we get the lock
- us->WaitPointer = NULL;
- }
- // Ooh, let's take it!
- else {
- Mutex->Owner = us;
- SHORTREL( &Mutex->Protector );
- }
-}
-
-/**
- * \brief Release a held mutex
- * \param Mutex Mutex to release
- */
-void Mutex_Release(tMutex *Mutex)
-{
- SHORTLOCK( &Mutex->Protector );
- //Log("Mutex_Release: (%p)", Mutex);
- if( Mutex->Waiting ) {
- Mutex->Owner = Mutex->Waiting; // Set owner
- Mutex->Waiting = Mutex->Waiting->Next; // Next!
- // Reset ->LastWaiting to NULL if we have just removed the last waiting thread
- // 2010-10-02 21:50 - Comemerating the death of the longest single
- // blocker in the Acess2 history. REMEMBER TO
- // FUCKING MAINTAIN YOUR FUCKING LISTS DIPWIT
- if( Mutex->LastWaiting == Mutex->Owner )
- Mutex->LastWaiting = NULL;
-
- // Wake new owner
- SHORTLOCK( &glThreadListLock );
- if( Mutex->Owner->Status != THREAD_STAT_ACTIVE )
- Threads_AddActive(Mutex->Owner);
- SHORTREL( &glThreadListLock );
- }
- else {
- Mutex->Owner = NULL;
- }
- SHORTREL( &Mutex->Protector );
-}
-
-/**
- * \brief Is this mutex locked?
- * \param Mutex Mutex pointer
- */
-int Mutex_IsLocked(tMutex *Mutex)
-{
- return Mutex->Owner != NULL;
-}
-