* threads.c
* - Threads handling
*/
+#define DEBUG 0
#include <acess.h>
#include <threads.h>
#include <threads_int.h>
+#include <mutex.h>
// === PROTOTYPES ===
void Threads_int_Init(void) __attribute__((constructor(101)));
// === GLOBALS ===
tThread *gThreads_List;
tThread __thread *lpThreads_This;
+ int giThreads_NextTID = 1;
+tShortSpinlock glThreadListLock;
// === CODE ===
void Threads_int_Init(void)
{
- lpThreads_This = Threads_int_CreateTCB(NULL);
+ if( !lpThreads_This ) {
+ lpThreads_This = Threads_int_CreateTCB(NULL);
+ Threads_SetName("ThreadZero");
+ }
}
tThread *Proc_GetCurThread(void)
return lpThreads_This;
}
-void Threads_PostEvent(tThread *Thread, Uint32 Events)
-{
- if( !Thread ) {
- // nope.avi
- return ;
- }
- Threads_int_MutexLock(Thread->Protector);
- Thread->PendingEvents |= Events;
- if( Thread->WaitingEvents & Events )
- Threads_int_SemSignal(Thread->WaitSemaphore);
- Threads_int_MutexRelease(Thread->Protector);
-}
-
-Uint32 Threads_WaitEvents(Uint32 Events)
-{
- if( Threads_int_ThreadingEnabled() ) {
- Log_Notice("Threads", "_WaitEvents: Threading disabled");
- return 0;
- }
- lpThreads_This->WaitingEvents = Events;
- Threads_int_SemWaitAll(lpThreads_This->WaitSemaphore);
- lpThreads_This->WaitingEvents = 0;
- Uint32 rv = lpThreads_This->PendingEvents;
- return rv;
-}
-
-void Threads_ClearEvent(Uint32 Mask)
-{
- if( Threads_int_ThreadingEnabled() ) {
- Log_Notice("Threads", "_ClearEvent: Threading disabled");
- return ;
- }
- Threads_int_MutexLock(lpThreads_This->Protector);
- lpThreads_This->PendingEvents &= ~Mask;
- Threads_int_MutexRelease(lpThreads_This->Protector);
-}
-
tUID Threads_GetUID(void) { return 0; }
tGID Threads_GetGID(void) { return 0; }
-tTID Threads_GetTID(void) { return 0; }
+tTID Threads_GetTID(void) { return lpThreads_This ? lpThreads_This->TID : 0; }
-int *Threads_GetMaxFD(void) { return &lpThreads_This->Process->MaxFDs; }
-char **Threads_GetCWD(void) { return &lpThreads_This->Process->CWD; }
-char **Threads_GetChroot(void) { return &lpThreads_This->Process->Chroot; }
+static inline tProcess* getproc(tProcess *Process) {
+ return (Process ? Process : lpThreads_This->Process);
+}
+int *Threads_GetMaxFD(tProcess *Process) { return &getproc(Process)->MaxFDs; }
+char **Threads_GetCWD(tProcess *Process) { return &getproc(Process)->CWD; }
+char **Threads_GetChroot(tProcess *Process) { return &getproc(Process)->Chroot; }
void **Threads_GetHandlesPtr(void) { return &lpThreads_This->Process->Handles; }
void Threads_Yield(void)
if( !lpThreads_This )
return 0;
- if( lpThreads_This->Name )
- free(lpThreads_This->Name);
- lpThreads_This->Name = strdup(Name);
+ if( lpThreads_This->ThreadName )
+ free(lpThreads_This->ThreadName);
+ lpThreads_This->ThreadName = strdup(Name);
return 0;
}
return &a_errno;
}
+tThread *Threads_RemActive(void)
+{
+ return lpThreads_This;
+}
+
+void Threads_AddActive(tThread *Thread)
+{
+ Thread->Status = THREAD_STAT_ACTIVE;
+ // Increment state-change semaphore
+ LOG("Waking %p(%i %s)", Thread, Thread->TID, Thread->ThreadName);
+ Threads_int_SemSignal(Thread->WaitSemaphore);
+}
+
struct sProcess *Threads_int_CreateProcess(void)
{
struct sProcess *ret = calloc(sizeof(struct sProcess), 1);
tThread *Threads_int_CreateTCB(tThread *Parent)
{
tThread *ret = calloc( sizeof(tThread), 1 );
+ ret->TID = giThreads_NextTID ++;
ret->WaitSemaphore = Threads_int_SemCreate();
- ret->Protector = Threads_int_MutexCreate();
+ //ret->Protector = Threads_int_MutexCreate();
if( !Parent )
{
}
}
+void Threads_int_WaitForStatusEnd(enum eThreadStatus Status)
+{
+ tThread *us = Proc_GetCurThread();
+ assert(Status != THREAD_STAT_ACTIVE);
+ assert(Status != THREAD_STAT_DEAD);
+ LOG("%i(%s) - %i", us->TID, us->ThreadName, Status);
+ while( us->Status == Status )
+ {
+ Threads_int_SemWaitAll(us->WaitSemaphore);
+ if( us->Status == Status )
+ Log_Warning("Threads", "Thread %p(%i %s) rescheduled while in %s state",
+ us, us->TID, us->ThreadName, casTHREAD_STAT[Status]);
+ }
+ LOG("%p(%i %s) Awake", us, us->TID, us->ThreadName);
+}
+
+int Threads_int_Sleep(enum eThreadStatus Status, void *Ptr, int Num, tThread **ListHead, tThread **ListTail, tShortSpinlock *Lock)
+{
+ tThread *us = Proc_GetCurThread();
+ us->Next = NULL;
+ // - Mark as sleeping
+ us->Status = Status;
+ us->WaitPointer = Ptr;
+ us->RetStatus = Num; // Use RetStatus as a temp variable
+
+ // - Add to waiting
+ if( ListTail ) {
+ if(*ListTail) {
+ (*ListTail)->Next = us;
+ }
+ else {
+ *ListHead = us;
+ }
+ *ListTail = us;
+ }
+ else if(ListHead) {
+ us->Next = *ListHead;
+ *ListHead = us;
+ }
+ else {
+ // nothing
+ }
+
+ if( Lock ) {
+ SHORTREL( Lock );
+ }
+ Threads_int_WaitForStatusEnd(Status);
+ us->WaitPointer = NULL;
+ return us->RetStatus;
+}
+