+ // Any Child
+ if(TID == -1) {
+ Log_Error("Threads", "TODO: Threads_WaitTID(TID=-1) - Any Child");
+ return -1;
+ }
+
+ // Any peer/child thread
+ if(TID == 0) {
+ Log_Error("Threads", "TODO: Threads_WaitTID(TID=0) - Any Child/Sibling");
+ return -1;
+ }
+
+ // TGID = abs(TID)
+ if(TID < -1) {
+ Log_Error("Threads", "TODO: Threads_WaitTID(TID<0) - TGID");
+ return -1;
+ }
+
+ // Specific Thread
+ if(TID > 0)
+ {
+ tThread *thread = Threads_GetThread(TID);
+ tThread *us = gpCurrentThread;
+ if(!thread) return -1;
+
+ us->Next = NULL;
+ us->Status = THREAD_STAT_WAITING;
+ // TODO: Locking
+ if(thread->WaitingThreadsEnd)
+ {
+ thread->WaitingThreadsEnd->Next = us;
+ thread->WaitingThreadsEnd = us;
+ }
+ else
+ {
+ thread->WaitingThreads = us;
+ thread->WaitingThreadsEnd = us;
+ }
+
+ Threads_WaitEvents( THREAD_EVENT_WAKEUP );
+
+ if(Status) *Status = thread->RetStatus;
+ thread->WaitingThreads = thread->WaitingThreads->Next;
+ us->Next = NULL;
+
+ return TID;
+ }
+
+ return 0;
+}
+
+void Threads_Exit(int TID, int Status)
+{
+ tThread *toWake;
+
+// VFS_Handles_Cleanup();
+
+ gpCurrentThread->RetStatus = Status;
+
+ #if 1
+ if( gpCurrentThread->Parent )
+ {
+ // Wait for the thread to be waited upon
+ while( gpCurrentThread->WaitingThreads == NULL )
+ Threads_Glue_Yield();
+ }
+ #endif
+
+ while( (toWake = gpCurrentThread->WaitingThreads) )
+ {
+ Log_Debug("Threads", "Threads_Exit - Waking %p %i '%s'", toWake, toWake->TID, toWake->ThreadName);
+
+ Threads_Wake(toWake);
+
+ while(gpCurrentThread->WaitingThreads == toWake)
+ Threads_Glue_Yield();
+ }
+}
+
+void Threads_Sleep()
+{
+ gpCurrentThread->Status = THREAD_STAT_SLEEPING;
+ Threads_int_WaitForStatusEnd(THREAD_STAT_SLEEPING);
+}
+
+int Threads_Wake(tThread *Thread)
+{
+ Thread->Status = THREAD_STAT_ACTIVE;
+ Threads_PostEvent(Thread, THREAD_EVENT_WAKEUP);
+ return 0;