X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Fthreads.c;h=67a2f637462e5b86252c40978b9cecee18cb21de;hb=97629e9f86a9cf7162649550b74b112a4fb1765f;hp=a8697d6352dbc9623a9f2a503b947470e7aec71e;hpb=9d64454b70e47aa5c29077e4dd59d28e14ca3bf2;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/threads.c b/KernelLand/Kernel/threads.c index a8697d63..67a2f637 100644 --- a/KernelLand/Kernel/threads.c +++ b/KernelLand/Kernel/threads.c @@ -66,6 +66,10 @@ tThread *Threads_RemActive(void); void Threads_ToggleTrace(int TID); void Threads_Fault(int Num); void Threads_SegFault(tVAddr Addr); +void Threads_PostSignal(int SignalNum); + int Threads_GetPendingSignal(void); +void Threads_SetSignalHandler(int SignalNum, void *Handler); +void *Threads_GetSignalHandler(int SignalNum); #if 0 int Threads_GetPID(void); int Threads_GetTID(void); @@ -212,7 +216,7 @@ int Threads_SetName(const char *NewName) if( IsHeap(oldname) ) free( oldname ); cur->ThreadName = strdup(NewName); -// Log_Debug("Threads", "Thread renamed to '%s'", NewName); + Log_Debug("Threads", "Thread renamed to '%s'", NewName); return 0; } @@ -485,6 +489,7 @@ tTID Threads_WaitTID(int TID, int *Status) if(TID > 0) { tTID ret; + // NOTE: Race condition - Other child dies, desired child dies, first death is 'lost' while( (ret = Threads_WaitTID(-1, Status)) != TID ) { if( ret == -1 ) @@ -711,6 +716,22 @@ void Threads_Yield(void) Proc_Reschedule(); } +/** + * \breif Wait for the thread status to not be a specified value + */ +void Threads_int_WaitForStatusEnd(enum eThreadStatus Status) +{ + tThread *us = Proc_GetCurThread(); + ASSERT(Status != THREAD_STAT_ACTIVE); + ASSERT(Status != THREAD_STAT_DEAD); + while( us->Status == Status ) + { + Proc_Reschedule(); + if( us->Status == Status ) + Debug("Thread %p(%i %s) rescheduled while in %s state", casTHREAD_STAT[Status]); + } +} + /** * \fn void Threads_Sleep(void) * \brief Take the current process off the run queue @@ -742,12 +763,7 @@ void Threads_Sleep(void) // Release Spinlock SHORTREL( &glThreadListLock ); - - while(cur->Status != THREAD_STAT_ACTIVE) { - Proc_Reschedule(); - if( cur->Status != THREAD_STAT_ACTIVE ) - Log("%i - Huh? why am I up? zzzz...", cur->TID); - } + Threads_int_WaitForStatusEnd(THREAD_STAT_SLEEPING); } @@ -992,6 +1008,62 @@ void Threads_SegFault(tVAddr Addr) //Threads_Exit( 0, -1 ); } + +void Threads_PostSignal(int SignalNum) +{ + tThread *cur = Proc_GetCurThread(); + cur->PendingSignal = SignalNum; + Threads_PostEvent(cur, THREAD_EVENT_SIGNAL); +} + +/** + */ +int Threads_GetPendingSignal(void) +{ + tThread *cur = Proc_GetCurThread(); + + // Atomic AND with 0 fetches and clears in one operation + return __sync_fetch_and_and( &cur->PendingSignal, 0 ); +} + +/* + * \brief Update the current thread's signal handler + */ +void Threads_SetSignalHandler(int SignalNum, void *Handler) +{ + if( SignalNum <= 0 || SignalNum >= NSIGNALS ) + return ; + if( !MM_IsUser(Handler) ) + return ; + Proc_GetCurThread()->Process->SignalHandlers[SignalNum] = Handler; +} + +/** + * \return 0 Ignore + */ +void *Threads_GetSignalHandler(int SignalNum) +{ + if( SignalNum <= 0 || SignalNum >= NSIGNALS ) + return NULL; + void *ret = Proc_GetCurThread()->Process->SignalHandlers[SignalNum]; + if( !ret ) + { + // Defaults + switch(SignalNum) + { + case SIGINT: + case SIGKILL: + case SIGSEGV: +// ret = User_Signal_Kill; + break; + default: + ret = NULL; + break; + } + } + return ret; +} + // --- Process Structure Access Functions --- tPGID Threads_GetPGID(void) { @@ -1061,9 +1133,20 @@ char **Threads_GetCWD(void) void Threads_int_DumpThread(tThread *thread) { + if( !thread ) { + Log(" %p NULL", thread); + return ; + } + if( !CheckMem(thread, sizeof(tThread)) ) { + Log(" %p INVAL", thread); + return ; + } + tPID pid = (thread->Process ? thread->Process->PID : -1); + const char *statstr = (thread->Status < sizeof(casTHREAD_STAT)/sizeof(casTHREAD_STAT[0]) + ? casTHREAD_STAT[thread->Status] : ""); Log(" %p %i (%i) - %s (CPU %i) - %i (%s)", - thread, thread->TID, thread->Process->PID, thread->ThreadName, thread->CurCPU, - thread->Status, casTHREAD_STAT[thread->Status] + thread, thread->TID, pid, thread->ThreadName, thread->CurCPU, + thread->Status, statstr ); switch(thread->Status) { @@ -1077,6 +1160,9 @@ void Threads_int_DumpThread(tThread *thread) ((tSemaphore*)thread->WaitPointer)->Name ); break; + case THREAD_STAT_EVENTSLEEP: + // TODO: Event mask + break; case THREAD_STAT_ZOMBIE: Log(" Return Status: %i", thread->RetStatus); break; @@ -1128,13 +1214,11 @@ void Threads_DumpActive(void) */ void Threads_Dump(void) { - tThread *thread; - Log("--- Thread Dump ---"); Threads_DumpActive(); Log("All Threads:"); - for(thread=gAllThreads;thread;thread=thread->GlobalNext) + for(tThread *thread = gAllThreads; thread; thread = thread->GlobalNext) { Threads_int_DumpThread(thread); }