a9eab7865e86244ded7a8cf9dd08bbcf529e7678
[tpg/acess2.git] / 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 Wait for an event to occur
46  */
47 Uint32 Threads_WaitEvents(Uint32 EventMask)
48 {
49         Uint32  rv;
50         tThread *us = Proc_GetCurThread();
51
52         ENTER("xEventMask", EventMask);
53
54         // Early return check
55         if( EventMask == 0 )
56         {
57                 LEAVE('i', 0);
58                 return 0;
59         }
60         
61         LOG("us = %p(%i %s)", us, us->TID, us->ThreadName);
62
63         // Check if a wait is needed
64         SHORTLOCK( &us->IsLocked );
65         while( !(us->EventState & EventMask) )
66         {
67                 LOG("Locked and preparing for wait");
68                 // Wait
69                 us->RetStatus = EventMask;      // HACK: Store EventMask in RetStatus
70                 SHORTLOCK( &glThreadListLock );
71                 us = Threads_RemActive();
72                 us->Status = THREAD_STAT_EVENTSLEEP;
73                 // Note stored anywhere because we're woken using other means
74                 SHORTREL( &glThreadListLock );
75                 SHORTREL( &us->IsLocked );
76                 while(us->Status == THREAD_STAT_EVENTSLEEP)     Threads_Yield();
77                 // Woken when lock is acquired
78                 SHORTLOCK( &us->IsLocked );
79         }
80         
81         // Get return value and clear changed event bits
82         rv = us->EventState & EventMask;
83         us->EventState &= ~EventMask;
84         
85         SHORTREL( &us->IsLocked );
86         
87         LEAVE('x', rv);
88         return rv;
89 }
90

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