1fd64592325ee191dd2f54eb69a1ba792d121306
[tpg/acess2.git] / KernelLand / Kernel / rwlock.c
1 /*
2  * Acess2 Kernel
3  * - By John Hodge (thePowersGang)
4  *
5  * rwlock.c
6  * - Reader-Writer Lockes
7  */
8 #define DEBUG   0
9 #include <acess.h>
10 #include <threads_int.h>
11 #include <rwlock.h>
12
13 // === PROTOTYPES ===
14 //
15 // Acquire as a reader (see rwlock.h for documentation)
16 //
17 int RWLock_AcquireRead(tRWLock *Lock)
18 {
19         LOG("Acquire RWLock Read %p", Lock);
20         // Get protector
21         SHORTLOCK( &Lock->Protector );
22         
23         // Check if the lock is already held by a writer
24         // - OR, there's a writer waiting to write
25         if( Lock->Owner || Lock->WriterWaiting )
26         {
27                 LOG("Waiting");
28                 Threads_int_Sleep(THREAD_STAT_RWLOCKSLEEP, Lock, 0,
29                         &Lock->ReaderWaiting, &Lock->ReaderWaitingLast,
30                         &Lock->Protector);
31         }
32         // Ooh, no problems then!
33         else
34         {
35                 Lock->Level++;
36                 SHORTREL( & Lock->Protector );
37         }
38         LOG("Obtained");
39         
40         return 0;
41 }
42
43 int RWLock_AcquireWrite(tRWLock *Lock)
44 {
45         LOG("Acquire RWLock Write %p", Lock);
46         
47         SHORTLOCK(&Lock->Protector);
48         if( Lock->Owner || Lock->Level != 0 )
49         {
50                 LOG("Waiting");
51                 Threads_int_Sleep(THREAD_STAT_RWLOCKSLEEP, Lock, 0,
52                         &Lock->WriterWaiting, &Lock->WriterWaitingLast,
53                         &Lock->Protector);
54         }
55         else
56         {
57                 // Nothing else is using the lock, nice :)
58                 Lock->Owner = Proc_GetCurThread();
59                 SHORTREL(&Lock->Protector);
60         }
61         LOG("Obtained");
62         return 0;
63 }
64
65 // Release a mutex
66 void RWLock_Release(tRWLock *Lock)
67 {
68         LOG("Release RWLock %p", Lock);
69         SHORTLOCK( &Lock->Protector );
70
71         if( Lock->Owner != Proc_GetCurThread() )
72                 Lock->Level --;
73         
74         // Writers first
75         if( Lock->WriterWaiting )
76         {
77                 Lock->Owner = Lock->WriterWaiting;      // Set owner
78                 Lock->WriterWaiting = Lock->WriterWaiting->Next;        // Next!
79                 
80                 // Wake new owner
81                 if( Lock->Owner->Status != THREAD_STAT_ACTIVE )
82                         Threads_AddActive(Lock->Owner);
83         }
84         else
85         {
86                 Lock->Owner = NULL;
87                 
88                 while( Lock->ReaderWaiting ) {
89                         Lock->Level ++;
90                         Threads_AddActive(Lock->ReaderWaiting);
91                         Lock->ReaderWaiting = Lock->ReaderWaiting->Next;
92                 }
93         }
94         SHORTREL( &Lock->Protector );
95 }
96
97 // === EXPORTS ===
98 EXPORT(RWLock_AcquireRead);
99 EXPORT(RWLock_AcquireWrite);
100 EXPORT(RWLock_Release);

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