X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Tools%2Fnativelib%2Fthreads.c;h=dafdc404ce6d87cac00a625a683266ebf6cb55c6;hb=bc856d707899a00153bb1575f1c05867177dfe41;hp=1231c439a45f7c4cac1b37428f4b6ea834c41e01;hpb=3241c317ee9f714eba6a0fa82de79cfe5f104993;p=tpg%2Facess2.git diff --git a/Tools/nativelib/threads.c b/Tools/nativelib/threads.c index 1231c439..dafdc404 100644 --- a/Tools/nativelib/threads.c +++ b/Tools/nativelib/threads.c @@ -5,9 +5,11 @@ * threads.c * - Threads handling */ +#define DEBUG 0 #include #include #include +#include // === PROTOTYPES === void Threads_int_Init(void) __attribute__((constructor(101))); @@ -16,11 +18,16 @@ tThread *Threads_int_CreateTCB(tThread *Parent); // === 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) @@ -28,47 +35,10 @@ 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; } @@ -91,9 +61,9 @@ int Threads_SetName(const char *Name) 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; } @@ -106,6 +76,19 @@ int *Threads_GetErrno(void) 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); @@ -118,8 +101,9 @@ struct sProcess *Threads_int_CreateProcess(void) 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 ) { @@ -154,3 +138,54 @@ struct sThread *Proc_SpawnWorker(void (*Fcn)(void*), void *Data) } } +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; +} +