Kernel - Cleaned up threads code a little, fixed event handling
[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                         // TODO: Does it matter if the thread is locked here?
36                         LOG("Waking thread %p(%i %s)", Thread, Thread->TID, Thread->ThreadName);
37                         Threads_AddActive(Thread);
38                 }
39         }
40         
41         SHORTREL( &Thread->IsLocked );
42         LEAVE('-');
43 }
44
45 /**
46  * \brief Wait for an event to occur
47  */
48 Uint32 Threads_WaitEvents(Uint32 EventMask)
49 {
50         Uint32  rv;
51         tThread *us = Proc_GetCurThread();
52
53         ENTER("xEventMask", EventMask);
54
55         // Early return check
56         if( EventMask == 0 )
57         {
58                 LEAVE('i', 0);
59                 return 0;
60         }
61         
62         LOG("us = %p(%i %s)", us, us->TID, us->ThreadName);
63
64         // Check if a wait is needed
65         SHORTLOCK( &us->IsLocked );
66         while( !(us->EventState & EventMask) )
67         {
68                 LOG("Locked and preparing for wait");
69                 // Wait
70                 us->RetStatus = EventMask;      // HACK: Store EventMask in RetStatus
71                 SHORTLOCK( &glThreadListLock );
72                 us = Threads_RemActive();
73                 us->Status = THREAD_STAT_EVENTSLEEP;
74                 // Note stored anywhere because we're woken using other means
75                 SHORTREL( &glThreadListLock );
76                 SHORTREL( &us->IsLocked );
77                 while(us->Status == THREAD_STAT_EVENTSLEEP)     Threads_Yield();
78                 // Woken when lock is acquired
79                 SHORTLOCK( &us->IsLocked );
80         }
81         
82         // Get return value and clear changed event bits
83         rv = us->EventState & EventMask;
84         us->EventState &= ~EventMask;
85         
86         SHORTREL( &us->IsLocked );
87         
88         LEAVE('x', rv);
89         return rv;
90 }
91

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