Kernel/x86 - Clean up some of the task switching code (possibly a little broken)
[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 <events.h>
11 #include <threads_int.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         default:
49                 break;
50         }
51         
52         SHORTREL( &Thread->IsLocked );
53         LEAVE('-');
54 }
55
56 /**
57  * \brief Clear an event without waiting
58  */
59 void Threads_ClearEvent(Uint32 EventMask)
60 {
61         Proc_GetCurThread()->EventState &= ~EventMask;
62 }
63
64 /**
65  * \brief Wait for an event to occur
66  */
67 Uint32 Threads_WaitEvents(Uint32 EventMask)
68 {
69         Uint32  rv;
70         tThread *us = Proc_GetCurThread();
71
72         ENTER("xEventMask", EventMask);
73
74         // Early return check
75         if( EventMask == 0 )
76         {
77                 LEAVE('i', 0);
78                 return 0;
79         }
80         
81         LOG("us = %p(%i %s)", us, us->TID, us->ThreadName);
82
83         // Check if a wait is needed
84         SHORTLOCK( &us->IsLocked );
85         LOG("Locked and preparing for wait");
86         if( (us->EventState & EventMask) == 0 )
87         {
88                 Threads_int_Sleep(THREAD_STAT_EVENTSLEEP, NULL, EventMask,
89                         &us, NULL, &us->IsLocked);
90                 // Woken when an event fires
91                 SHORTLOCK( &us->IsLocked );
92         }
93         
94         // Get return value and clear changed event bits
95         rv = us->EventState & EventMask;
96         us->EventState &= ~EventMask;
97         
98         SHORTREL( &us->IsLocked );
99         
100         LEAVE('x', rv);
101         return rv;
102 }
103

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