Merge branch 'master' of git://localhost/acess2
[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         switch(Thread->Status)
30         {
31         // Waiting on this event?
32         case THREAD_STAT_EVENTSLEEP:
33                 if( (Uint32)Thread->RetStatus & EventMask )
34                 {
35                         // Wake up
36                         LOG("Waking thread %p(%i %s)", Thread, Thread->TID, Thread->ThreadName);
37                         Threads_AddActive(Thread);
38                 }
39                 break;
40         case THREAD_STAT_SEMAPHORESLEEP:
41                 if( EventMask & THREAD_EVENT_TIMER )
42                 {
43                         LOG("Waking %p(%i %s) from semaphore on timer",
44                                 Thread, Thread->TID, Thread->ThreadName);
45                         Semaphore_ForceWake(Thread);
46                 }
47                 break;
48         }
49         
50         SHORTREL( &Thread->IsLocked );
51         LEAVE('-');
52 }
53
54 /**
55  * \brief Clear an event without waiting
56  */
57 void Threads_ClearEvent(Uint32 EventMask)
58 {
59         Proc_GetCurThread()->EventState &= ~EventMask;
60 }
61
62 /**
63  * \brief Wait for an event to occur
64  */
65 Uint32 Threads_WaitEvents(Uint32 EventMask)
66 {
67         Uint32  rv;
68         tThread *us = Proc_GetCurThread();
69
70         ENTER("xEventMask", EventMask);
71
72         // Early return check
73         if( EventMask == 0 )
74         {
75                 LEAVE('i', 0);
76                 return 0;
77         }
78         
79         LOG("us = %p(%i %s)", us, us->TID, us->ThreadName);
80
81         // Check if a wait is needed
82         SHORTLOCK( &us->IsLocked );
83         while( !(us->EventState & EventMask) )
84         {
85                 LOG("Locked and preparing for wait");
86                 // Wait
87                 us->RetStatus = EventMask;      // HACK: Store EventMask in RetStatus
88                 SHORTLOCK( &glThreadListLock );
89                 us = Threads_RemActive();
90                 us->Status = THREAD_STAT_EVENTSLEEP;
91                 // Note stored anywhere because we're woken using other means
92                 SHORTREL( &glThreadListLock );
93                 SHORTREL( &us->IsLocked );
94                 Threads_int_WaitForStatusEnd(THREAD_STAT_EVENTSLEEP);
95                 // Woken when lock is acquired
96                 SHORTLOCK( &us->IsLocked );
97         }
98         
99         // Get return value and clear changed event bits
100         rv = us->EventState & EventMask;
101         us->EventState &= ~EventMask;
102         
103         SHORTREL( &us->IsLocked );
104         
105         LEAVE('x', rv);
106         return rv;
107 }
108

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