X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Tools%2Fnativelib%2Fthreads.c;h=aec7076e0c8c3872e30491af482733a21a338c74;hb=12040654ff2053cc97de492180b582027b6de60b;hp=d5f04652fbc450dd2fe9c95c70248066ec984fd4;hpb=0ab008276f88801b5a5a2ed8e96c285e524ead2c;p=tpg%2Facess2.git diff --git a/Tools/nativelib/threads.c b/Tools/nativelib/threads.c index d5f04652..aec7076e 100644 --- a/Tools/nativelib/threads.c +++ b/Tools/nativelib/threads.c @@ -9,11 +9,23 @@ #include #include +// === PROTOTYPES === +void Threads_int_Init(void) __attribute__((constructor(101))); +tThread *Threads_int_CreateTCB(tThread *Parent); + // === GLOBALS === - int gbThreads_MultithreadingEnabled; +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); + Threads_SetName("ThreadZero"); +} + tThread *Proc_GetCurThread(void) { return lpThreads_This; @@ -21,41 +33,55 @@ tThread *Proc_GetCurThread(void) void Threads_PostEvent(tThread *Thread, Uint32 Events) { - Threads_int_LockMutex(Thread->Protector); + if( !Thread ) { + // nope.avi + return ; + } + SHORTLOCK( &Thread->IsLocked ); Thread->PendingEvents |= Events; if( Thread->WaitingEvents & Events ) - Threads_int_SemaphoreSignal(Thread->WaitSemaphore); - Threads_int_ReleaseMutex(Thread->Protector); + Threads_int_SemSignal(Thread->WaitSemaphore); + SHORTREL( &Thread->IsLocked ); } Uint32 Threads_WaitEvents(Uint32 Events) { - Thread->WaitingEvents = Events; - Threads_int_SemaphoreWaitAll(Thread->WaitSemaphore); - Thread->WaitingEvents = 0; - Uint32 rv = Thread->PendingEvents; + 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) { - Threads_int_LockMutex(Thread->Protector); + if( !Threads_int_ThreadingEnabled() ) { + Log_Notice("Threads", "_ClearEvent: Threading disabled"); + return ; + } + SHORTLOCK(&lpThreads_This->IsLocked); lpThreads_This->PendingEvents &= ~Mask; - Threads_int_ReleaseMutex(Thread->Protector); + SHORTREL(&lpThreads_This->IsLocked); } 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) { static int max_fd=32; return &max_fd; } -char **Threads_GetCWD(void) { static char *cwd; return &cwd; } -char **Threads_GetChroot(void) { static char *chroot; return &chroot; } +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; } +void **Threads_GetHandlesPtr(void) { return &lpThreads_This->Process->Handles; } void Threads_Yield(void) { - Log_Warning("Threads", "Threads_Yield DEFINITELY shouldn't be used"); + Log_KernelPanic("Threads", "Threads_Yield DEFINITELY shouldn't be used (%p)", + __builtin_return_address(0)); } void Threads_Sleep(void) @@ -63,35 +89,90 @@ void Threads_Sleep(void) Log_Warning("Threads", "Threads_Sleep shouldn't be used"); } +void Threads_int_WaitForStatusEnd(enum eThreadStatus Status) +{ + while( lpThreads_This->Status != Status ) + Threads_int_SemWaitAll(lpThreads_This->WaitSemaphore); +} + int Threads_SetName(const char *Name) { - Log_Notice("Threads", "TODO: Threads_SetName('%s')", Name); + if( !lpThreads_This ) + return 0; + + if( lpThreads_This->ThreadName ) + free(lpThreads_This->ThreadName); + lpThreads_This->ThreadName = strdup(Name); + return 0; } int *Threads_GetErrno(void) __attribute__ ((weak)); -int *Threads_GetErrno(void)// __attribute__ ((weak)) +int *Threads_GetErrno(void) { static int a_errno; return &a_errno; } +tThread *Threads_RemActive(void) +{ + return lpThreads_This; +} + +void Threads_AddActive(tThread *Thread) +{ + Thread->Status = THREAD_STAT_ACTIVE; + // Increment state-change semaphore + Threads_int_SemSignal(Thread->WaitSemaphore); +} + +struct sProcess *Threads_int_CreateProcess(void) +{ + struct sProcess *ret = calloc(sizeof(struct sProcess), 1); + + ret->MaxFDs = 32; + + return ret; +} + +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(); + + if( !Parent ) + { + ret->Process = Threads_int_CreateProcess(); + } + else + ret->Process = Parent->Process; + + ret->ProcNext = ret->Process->Threads; + ret->Process->Threads = ret; + + ret->Next = gThreads_List; + gThreads_List = ret; + + return ret; +} + struct sThread *Proc_SpawnWorker(void (*Fcn)(void*), void *Data) { - if( !gbThreads_MultithreadingEnabled ) + if( !Threads_int_ThreadingEnabled() ) { Log_Error("Threads", "Multithreading is disabled in this build"); return NULL; } else { - tThread *ret = malloc( sizeof(tThread) ); + tThread *ret = Threads_int_CreateTCB(lpThreads_This); ret->SpawnFcn = Fcn; ret->SpawnData = Data; Threads_int_CreateThread(ret); - Log_Error("Threads", "TODO - Use pthreads to impliment Proc_SpawnWorker"); - return NULL; + return ret; } }