Kernel - Slight reworks to timer code
[tpg/acess2.git] / Kernel / mutex.c
1 /*
2  * Acess2 Kernel
3  * - By John Hodge (thePowersGang)
4  *
5  * mutex.c
6  * - Mutexes
7  */
8 #include <acess.h>
9 #include <threads_int.h>
10 #include <mutex.h>
11
12 // === PROTOTYPES ===
13 #if 0
14  int    Mutex_Acquire(tMutex *Mutex);
15 void    Mutex_Release(tMutex *Mutex);
16  int    Mutex_IsLocked(tMutex *Mutex);
17 #endif
18
19 // === CODE ===
20 //
21 // Acquire mutex (see mutex.h for documentation)
22 //
23 int Mutex_Acquire(tMutex *Mutex)
24 {
25         tThread *us = Proc_GetCurThread();
26         
27         // Get protector
28         SHORTLOCK( &Mutex->Protector );
29         
30 //      Log("Mutex_Acquire: (%p)", Mutex);
31         
32         // Check if the lock is already held
33         if( Mutex->Owner ) {
34                 SHORTLOCK( &glThreadListLock );
35                 // - Remove from active list
36                 us = Threads_RemActive();
37                 us->Next = NULL;
38                 // - Mark as sleeping
39                 us->Status = THREAD_STAT_MUTEXSLEEP;
40                 us->WaitPointer = Mutex;
41                 
42                 // - Add to waiting
43                 if(Mutex->LastWaiting) {
44                         Mutex->LastWaiting->Next = us;
45                         Mutex->LastWaiting = us;
46                 }
47                 else {
48                         Mutex->Waiting = us;
49                         Mutex->LastWaiting = us;
50                 }
51                 
52                 #if DEBUG_TRACE_STATE
53                 Log("%p (%i %s) waiting on mutex %p",
54                         us, us->TID, us->ThreadName, Mutex);
55                 #endif
56                 
57                 #if 0
58                 {
59                          int    i = 0;
60                         tThread *t;
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);
64                 }
65                 #endif
66                 
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;
72         }
73         // Ooh, let's take it!
74         else {
75                 Mutex->Owner = us;
76                 SHORTREL( &Mutex->Protector );
77         }
78         
79         #if 0
80         extern tMutex   glPhysAlloc;
81         if( Mutex != &glPhysAlloc )
82                 LogF("Mutex %p taken by %i %p\n", Mutex, us->TID, __builtin_return_address(0));
83         #endif
84         
85         return 0;
86 }
87
88 // Release a mutex
89 void Mutex_Release(tMutex *Mutex)
90 {
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;
99                 
100                 // Wake new owner
101                 if( Mutex->Owner->Status != THREAD_STAT_ACTIVE )
102                         Threads_AddActive(Mutex->Owner);
103         }
104         else {
105                 Mutex->Owner = NULL;
106         }
107         SHORTREL( &Mutex->Protector );
108         
109         #if 0
110         extern tMutex   glPhysAlloc;
111         if( Mutex != &glPhysAlloc )
112                 LogF("Mutex %p released by %i %p\n", Mutex, Threads_GetTID(), __builtin_return_address(0));
113         #endif
114 }
115
116 // Check if a mutex is locked
117 int Mutex_IsLocked(tMutex *Mutex)
118 {
119         return Mutex->Owner != NULL;
120 }
121
122 // === EXPORTS ===
123 EXPORT(Mutex_Acquire);
124 EXPORT(Mutex_Release);
125 EXPORT(Mutex_IsLocked);

UCC git Repository :: git.ucc.asn.au