Kernel/x86 - Clean up some of the task switching code (possibly a little broken)
[tpg/acess2.git] / KernelLand / 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                 // Sleep on the lock
35                 Threads_int_Sleep(THREAD_STAT_MUTEXSLEEP,
36                         Mutex, 0,
37                         &Mutex->Waiting, &Mutex->LastWaiting, &Mutex->Protector);
38                 // - We're only woken when we get the lock
39         }
40         else {
41                 // If not, just obtain it
42                 Mutex->Owner = us;
43                 SHORTREL( &Mutex->Protector );
44         }
45         
46         #if 0
47         extern tMutex   glPhysAlloc;
48         if( Mutex != &glPhysAlloc )
49                 LogF("Mutex %p taken by %i %p\n", Mutex, us->TID, __builtin_return_address(0));
50         #endif
51         
52         return 0;
53 }
54
55 // Release a mutex
56 void Mutex_Release(tMutex *Mutex)
57 {
58         SHORTLOCK( &Mutex->Protector );
59         //Log("Mutex_Release: (%p)", Mutex);
60         if( Mutex->Waiting ) {
61                 Mutex->Owner = Mutex->Waiting;  // Set owner
62                 Mutex->Waiting = Mutex->Waiting->Next;  // Next!
63                 // Reset ->LastWaiting to NULL if we have just removed the last waiting thread
64                 if( Mutex->LastWaiting == Mutex->Owner )
65                         Mutex->LastWaiting = NULL;
66                 
67                 // Wake new owner
68                 if( Mutex->Owner->Status != THREAD_STAT_ACTIVE )
69                         Threads_AddActive(Mutex->Owner);
70         }
71         else {
72                 Mutex->Owner = NULL;
73         }
74         SHORTREL( &Mutex->Protector );
75         
76         #if 0
77         extern tMutex   glPhysAlloc;
78         if( Mutex != &glPhysAlloc )
79                 LogF("Mutex %p released by %i %p\n", Mutex, Threads_GetTID(), __builtin_return_address(0));
80         #endif
81 }
82
83 // Check if a mutex is locked
84 int Mutex_IsLocked(tMutex *Mutex)
85 {
86         return Mutex->Owner != NULL;
87 }
88
89 // === EXPORTS ===
90 EXPORT(Mutex_Acquire);
91 EXPORT(Mutex_Release);
92 EXPORT(Mutex_IsLocked);

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