CLIShell - PTY signal support (and kernel fixes)
[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         if( Lock->Owner )
25         {
26                 LOG("Waiting");
27                 Threads_int_Sleep(THREAD_STAT_RWLOCKSLEEP, Lock, 0,
28                         &Lock->ReaderWaiting, &Lock->ReaderWaitingLast,
29                         &Lock->Protector);
30         }
31         // Ooh, no problems then!
32         else
33         {
34                 Lock->Level++;
35                 SHORTREL( & Lock->Protector );
36         }
37         LOG("Obtained");
38         
39         return 0;
40 }
41
42 int RWLock_AcquireWrite(tRWLock *Lock)
43 {
44         LOG("Acquire RWLock Write %p", Lock);
45         
46         SHORTLOCK(&Lock->Protector);
47         if( Lock->Owner || Lock->Level != 0 )
48         {
49                 LOG("Waiting");
50                 Threads_int_Sleep(THREAD_STAT_RWLOCKSLEEP, Lock, 0,
51                         &Lock->WriterWaiting, &Lock->WriterWaitingLast,
52                         &Lock->Protector);
53         }
54         else
55         {
56                 // Nothing else is using the lock, nice :)
57                 Lock->Owner = Proc_GetCurThread();
58                 SHORTREL(&Lock->Protector);
59         }
60         LOG("Obtained");
61         return 0;
62 }
63
64 // Release a mutex
65 void RWLock_Release(tRWLock *Lock)
66 {
67         LOG("Release RWLock %p", Lock);
68         SHORTLOCK( &Lock->Protector );
69
70         if( Lock->Owner != Proc_GetCurThread() )
71                 Lock->Level --;
72         
73         // Writers first
74         if( Lock->WriterWaiting )
75         {
76                 Lock->Owner = Lock->WriterWaiting;      // Set owner
77                 Lock->WriterWaiting = Lock->WriterWaiting->Next;        // Next!
78                 
79                 // Wake new owner
80                 if( Lock->Owner->Status != THREAD_STAT_ACTIVE )
81                         Threads_AddActive(Lock->Owner);
82         }
83         else
84         {
85                 Lock->Owner = NULL;
86                 
87                 while( Lock->ReaderWaiting ) {
88                         Lock->Level ++;
89                         Threads_AddActive(Lock->ReaderWaiting);
90                         Lock->ReaderWaiting = Lock->ReaderWaiting->Next;
91                 }
92         }
93         SHORTREL( &Lock->Protector );
94 }
95
96 // === EXPORTS ===
97 EXPORT(RWLock_AcquireRead);
98 EXPORT(RWLock_AcquireWrite);
99 EXPORT(RWLock_Release);

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