3 * - By John Hodge (thePowersGang)
9 #include <threads_int.h>
14 int Mutex_Acquire(tMutex *Mutex);
15 void Mutex_Release(tMutex *Mutex);
16 int Mutex_IsLocked(tMutex *Mutex);
21 // Acquire mutex (see mutex.h for documentation)
23 int Mutex_Acquire(tMutex *Mutex)
25 tThread *us = Proc_GetCurThread();
28 SHORTLOCK( &Mutex->Protector );
30 // Log("Mutex_Acquire: (%p)", Mutex);
32 // Check if the lock is already held
34 SHORTLOCK( &glThreadListLock );
35 // - Remove from active list
36 us = Threads_RemActive();
39 us->Status = THREAD_STAT_MUTEXSLEEP;
40 us->WaitPointer = Mutex;
43 if(Mutex->LastWaiting) {
44 Mutex->LastWaiting->Next = us;
45 Mutex->LastWaiting = us;
49 Mutex->LastWaiting = us;
53 Log("%p (%i %s) waiting on mutex %p",
54 us, us->TID, us->ThreadName, Mutex);
61 for( t = Mutex->Waiting; t; t = t->Next, i++ )
62 Log("[%i] (tMutex)%p->Waiting[%i] = %p (%i %s)", us->TID, Mutex, i,
63 t, t->TID, t->ThreadName);
67 SHORTREL( &glThreadListLock );
68 SHORTREL( &Mutex->Protector );
69 while(us->Status == THREAD_STAT_MUTEXSLEEP) Threads_Yield();
70 // We're only woken when we get the lock
71 us->WaitPointer = NULL;
73 // Ooh, let's take it!
76 SHORTREL( &Mutex->Protector );
80 extern tMutex glPhysAlloc;
81 if( Mutex != &glPhysAlloc )
82 LogF("Mutex %p taken by %i %p\n", Mutex, us->TID, __builtin_return_address(0));
89 void Mutex_Release(tMutex *Mutex)
91 SHORTLOCK( &Mutex->Protector );
92 //Log("Mutex_Release: (%p)", Mutex);
93 if( Mutex->Waiting ) {
94 Mutex->Owner = Mutex->Waiting; // Set owner
95 Mutex->Waiting = Mutex->Waiting->Next; // Next!
96 // Reset ->LastWaiting to NULL if we have just removed the last waiting thread
97 if( Mutex->LastWaiting == Mutex->Owner )
98 Mutex->LastWaiting = NULL;
101 if( Mutex->Owner->Status != THREAD_STAT_ACTIVE )
102 Threads_AddActive(Mutex->Owner);
107 SHORTREL( &Mutex->Protector );
110 extern tMutex glPhysAlloc;
111 if( Mutex != &glPhysAlloc )
112 LogF("Mutex %p released by %i %p\n", Mutex, Threads_GetTID(), __builtin_return_address(0));
116 // Check if a mutex is locked
117 int Mutex_IsLocked(tMutex *Mutex)
119 return Mutex->Owner != NULL;
123 EXPORT(Mutex_Acquire);
124 EXPORT(Mutex_Release);
125 EXPORT(Mutex_IsLocked);