Kernel - Added another event and allowed clearing of events
[tpg/acess2.git] / KernelLand / Kernel / events.c
1 /*
2  * Acess2 Kernel
3  * - By John Hodge (thePowersGang)
4  *
5  * events.c
6  * - Thread level event handling
7  */
8 #define DEBUG   0
9 #include <acess.h>
10 #include <threads_int.h>
11 #include <events.h>
12
13 // === CODE ===
14 void Threads_PostEvent(tThread *Thread, Uint32 EventMask)
15 {
16         // Sanity checking
17         if( !Thread )   return ;
18         if( EventMask == 0 )    return ;
19         // TODO: Check that only one bit is set?
20         
21         ENTER("pThread xEventMask", Thread, EventMask);
22
23         SHORTLOCK( &Thread->IsLocked );
24
25         Thread->EventState |= EventMask;
26         LOG("Thread->EventState = 0x%x", Thread->EventState);
27         
28         // Currently sleeping on an event?
29         if( Thread->Status == THREAD_STAT_EVENTSLEEP )
30         {
31                 // Waiting on this event?
32                 if( (Uint32)Thread->RetStatus & EventMask )
33                 {
34                         // Wake up
35                         LOG("Waking thread %p(%i %s)", Thread, Thread->TID, Thread->ThreadName);
36                         Threads_AddActive(Thread);
37                 }
38         }
39         
40         SHORTREL( &Thread->IsLocked );
41         LEAVE('-');
42 }
43
44 /**
45  * \brief Clear an event without waiting
46  */
47 void Threads_ClearEvent(Uint32 EventMask)
48 {
49         Proc_GetCurThread()->EventState &= ~EventMask;
50 }
51
52 /**
53  * \brief Wait for an event to occur
54  */
55 Uint32 Threads_WaitEvents(Uint32 EventMask)
56 {
57         Uint32  rv;
58         tThread *us = Proc_GetCurThread();
59
60         ENTER("xEventMask", EventMask);
61
62         // Early return check
63         if( EventMask == 0 )
64         {
65                 LEAVE('i', 0);
66                 return 0;
67         }
68         
69         LOG("us = %p(%i %s)", us, us->TID, us->ThreadName);
70
71         // Check if a wait is needed
72         SHORTLOCK( &us->IsLocked );
73         while( !(us->EventState & EventMask) )
74         {
75                 LOG("Locked and preparing for wait");
76                 // Wait
77                 us->RetStatus = EventMask;      // HACK: Store EventMask in RetStatus
78                 SHORTLOCK( &glThreadListLock );
79                 us = Threads_RemActive();
80                 us->Status = THREAD_STAT_EVENTSLEEP;
81                 // Note stored anywhere because we're woken using other means
82                 SHORTREL( &glThreadListLock );
83                 SHORTREL( &us->IsLocked );
84                 while(us->Status == THREAD_STAT_EVENTSLEEP)     Threads_Yield();
85                 // Woken when lock is acquired
86                 SHORTLOCK( &us->IsLocked );
87         }
88         
89         // Get return value and clear changed event bits
90         rv = us->EventState & EventMask;
91         us->EventState &= ~EventMask;
92         
93         SHORTREL( &us->IsLocked );
94         
95         LEAVE('x', rv);
96         return rv;
97 }
98

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