* events.c
* - Thread level event handling
*/
+#define DEBUG 0
#include <acess.h>
#include <threads_int.h>
#include <events.h>
// === CODE ===
-void Threads_PostEvent(tThread *Thread, int EventID)
+void Threads_PostEvent(tThread *Thread, Uint32 EventMask)
{
- if( EventID < 0 || EventID > N_EVENTS )
- {
- return ;
- }
+ // Sanity checking
+ if( !Thread ) return ;
+ if( EventMask == 0 ) return ;
+ // TODO: Check that only one bit is set?
- SHORTLOCK( Thread->IsLocked );
+ ENTER("pThread xEventMask", Thread, EventMask);
+
+ SHORTLOCK( &Thread->IsLocked );
- Thread->EventState |= 1 << EventID;
+ Thread->EventState |= EventMask;
+ LOG("Thread->EventState = 0x%x", Thread->EventState);
// Currently sleeping on an event?
- if( Thread->State == THREAD_STAT_EVENTSLEEP )
+ if( Thread->Status == THREAD_STAT_EVENTSLEEP )
{
// Waiting on this event?
- if( (Uint32)Thread->RetStatus & (1 << EventID) )
+ if( (Uint32)Thread->RetStatus & EventMask )
{
// Wake up
+ LOG("Waking thread %p(%i %s)", Thread, Thread->TID, Thread->ThreadName);
Threads_AddActive(Thread);
}
}
- SHORTREL( Thread->IsLocked );
+ SHORTREL( &Thread->IsLocked );
+ LEAVE('-');
}
+/**
+ * \brief Wait for an event to occur
+ */
Uint32 Threads_WaitEvents(Uint32 EventMask)
{
Uint32 rv;
tThread *us = Proc_GetCurThread();
+ ENTER("xEventMask", EventMask);
+
// Early return check
if( EventMask == 0 )
{
+ LEAVE('i', 0);
return 0;
}
+ LOG("us = %p(%i %s)", us, us->TID, us->ThreadName);
+
// Check if a wait is needed
SHORTLOCK( &us->IsLocked );
- if( !(us->EventState & EventMask) )
+ while( !(us->EventState & EventMask) )
{
+ LOG("Locked and preparing for wait");
// Wait
us->RetStatus = EventMask; // HACK: Store EventMask in RetStatus
SHORTLOCK( &glThreadListLock );
us = Threads_RemActive();
us->Status = THREAD_STAT_EVENTSLEEP;
+ // Note stored anywhere because we're woken using other means
SHORTREL( &glThreadListLock );
SHORTREL( &us->IsLocked );
- while(us->Status == THREAD_STAT_MUTEXSLEEP) Threads_Yield();
+ while(us->Status == THREAD_STAT_EVENTSLEEP) Threads_Yield();
// Woken when lock is acquired
SHORTLOCK( &us->IsLocked );
}
rv = us->EventState & EventMask;
us->EventState &= ~EventMask;
- SHORTREL( us->IsLocked );
+ SHORTREL( &us->IsLocked );
+ LEAVE('x', rv);
return rv;
}