+
+int Threads_CreateRootProcess(void)
+{
+ tThread *thread = Threads_CloneTCB(&gThreadZero, true);
+
+ // Handle list is created on first open
+
+ return thread->Process->PID;
+}
+
+int Threads_Fork(void)
+{
+ tThread *thread = Threads_CloneTCB(gpCurrentThread, true);
+
+ // Duplicate the VFS handles (and nodes) from vfs_handle.c
+ VFS_CloneHandleList(thread->Process->PID);
+
+ return thread->Process->PID;
+}
+
+int Threads_Spawn(int nFD, int FDs[], struct s_sys_spawninfo *info)
+{
+ tThread *thread = Threads_CloneTCB(gpCurrentThread, true);
+ if( info )
+ {
+ // TODO: PGID?
+ //if( info->flags & SPAWNFLAG_NEWPGID )
+ // thread->PGID = thread->PID;
+ if( thread->Process->UID == 0 )
+ {
+ if( info->gid )
+ thread->Process->GID = info->gid;
+ if( info->uid )
+ thread->Process->UID = info->uid;
+ }
+ }
+
+ VFS_CloneHandlesFromList(thread->Process->PID, nFD, FDs);
+
+ return thread->Process->PID;
+}
+
+// ----
+// ----
+void Threads_int_Terminate(tThread *Thread)
+{
+ Thread->RetStatus = -1;
+ Threads_AddActive(Thread);
+}
+
+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 )
+ {
+ if( Threads_Glue_SemWait(gpCurrentThread->EventSem, INT_MAX) == -1 ) {
+ Log_Warning("Threads", "Wait on eventsem of %p, %p failed",
+ gpCurrentThread, gpCurrentThread->EventSem);
+ return ;
+ }
+ if( us->Status == Status )
+ Log_Warning("Threads", "Thread %p(%i %s) rescheduled while in %s state",
+ us, us->TID, us->ThreadName, casTHREAD_STAT[Status]);
+ }
+}
+
+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 {
+ *ListHead = us;
+ }
+
+ if( Lock ) {
+ SHORTREL( Lock );
+ }
+ Threads_int_WaitForStatusEnd(Status);
+ us->WaitPointer = NULL;
+ return us->RetStatus;
+}
+
+void Threads_AddActive(tThread *Thread)
+{
+ LOG("%i(%s)", Thread->TID, Thread->ThreadName);
+ Thread->Status = THREAD_STAT_ACTIVE;
+ Threads_Glue_SemSignal(Thread->EventSem, 1);
+}
+
+// --------------------------------------------------------------------
+// Signals
+// --------------------------------------------------------------------
+void Threads_PostSignal(int SigNum)
+{
+ Log_Error("Threads", "TODO: %s", __func__);
+}
+void Threads_SignalGroup(tPGID PGID, int SignalNum)
+{
+ Log_Error("Threads", "TODO: %s", __func__);
+}
+