+ if(ID == -1) {
+ return Proc_GetCurThread()->ThreadName;
+ }
+ return Threads_GetThread(ID)->ThreadName;
+}
+
+/**
+ * \fn void Threads_SetPriority(tThread *Thread, int Pri)
+ * \brief Sets the priority of a task
+ * \param Thread Thread to update ticket count (NULL means current thread)
+ * \param Pri New priority
+ */
+void Threads_SetPriority(tThread *Thread, int Pri)
+{
+ // Get current thread
+ if(Thread == NULL) Thread = Proc_GetCurThread();
+ // Bounds checking
+ // - If < 0, set to lowest priority
+ // - Minumum priority is actualy a high number, 0 is highest
+ if(Pri < 0) Pri = MIN_PRIORITY;
+ if(Pri > MIN_PRIORITY) Pri = MIN_PRIORITY;
+
+ // Do we actually have to do anything?
+ if( Pri == Thread->Priority ) return;
+
+ #if SCHEDULER_TYPE == SCHED_RR_PRI
+ if( Thread != Proc_GetCurThread() )
+ {
+ SHORTLOCK( &glThreadListLock );
+ // Remove from old priority
+ Threads_int_DelFromQueue( &gaActiveThreads[Thread->Priority], Thread );
+ // And add to new
+ Threads_int_AddToList( &gaActiveThreads[Pri], Thread );
+ Thread->Priority = Pri;
+ SHORTREL( &glThreadListLock );
+ }
+ else
+ Thread->Priority = Pri;
+ #else
+ // If this isn't the current thread, we need to lock
+ if( Thread != Proc_GetCurThread() )
+ {
+ SHORTLOCK( &glThreadListLock );
+
+ #if SCHEDULER_TYPE == SCHED_LOTTERY
+ giFreeTickets -= caiTICKET_COUNTS[Thread->Priority] - caiTICKET_COUNTS[Pri];
+ # if DEBUG_TRACE_TICKETS
+ Log("Threads_SetTickets: new giFreeTickets = %i [-%i+%i]",
+ giFreeTickets,
+ caiTICKET_COUNTS[Thread->Priority], caiTICKET_COUNTS[Pri]);
+ # endif
+ #endif
+ Thread->Priority = Pri;
+ SHORTREL( &glThreadListLock );
+ }
+ else
+ Thread->Priority = Pri;
+ #endif
+
+ #if DEBUG_TRACE_STATE
+ Log("Threads_SetPriority: %p(%i %s) pri set %i",
+ Thread, Thread->TID, Thread->ThreadName,
+ Pri);
+ #endif
+}
+
+/**
+ * \brief Clone the TCB of the current thread
+ * \param Flags Flags for something... (What is this for?)
+ */
+tThread *Threads_CloneTCB(Uint Flags)
+{
+ tThread *cur, *new;
+ cur = Proc_GetCurThread();
+
+ // Allocate and duplicate
+ new = malloc(sizeof(tThread));
+ if(new == NULL) { errno = -ENOMEM; return NULL; }
+ memcpy(new, cur, sizeof(tThread));
+
+ new->CurCPU = -1;
+ new->Next = NULL;
+ memset( &new->IsLocked, 0, sizeof(new->IsLocked));
+ new->Status = THREAD_STAT_PREINIT;
+ new->RetStatus = 0;
+
+ // Get Thread ID
+ new->TID = giNextTID++;
+ new->Parent = cur;
+ new->bInstrTrace = 0;
+
+ // Clone Name
+ new->ThreadName = strdup(cur->ThreadName);
+
+ // Set Thread Group ID (PID)
+ if(Flags & CLONE_VM) {
+ tProcess *newproc, *oldproc;
+ oldproc = cur->Process;
+ new->Process = malloc( sizeof(struct sProcess) );
+ newproc = new->Process;
+ newproc->PID = new->TID;
+ newproc->UID = oldproc->UID;
+ newproc->GID = oldproc->GID;
+ newproc->MaxFD = oldproc->MaxFD;
+ if( oldproc->CurrentWorkingDir )
+ newproc->CurrentWorkingDir = strdup( oldproc->CurrentWorkingDir );
+ else
+ newproc->CurrentWorkingDir = NULL;
+ if( oldproc->RootDir )
+ newproc->RootDir = strdup( oldproc->RootDir );
+ else
+ newproc->RootDir = NULL;
+ newproc->nThreads = 1;
+ // Reference all handles in the VFS
+ VFS_ReferenceUserHandles();
+ }
+ else {
+ new->Process->nThreads ++;
+ }
+
+ // Messages are not inherited
+ new->Messages = NULL;
+ new->LastMessage = NULL;
+
+ // Set State
+ new->Remaining = new->Quantum = cur->Quantum;
+ new->Priority = cur->Priority;
+ new->_errno = 0;
+
+ // Set Signal Handlers
+ new->CurFaultNum = 0;
+ new->FaultHandler = cur->FaultHandler;
+
+ // Maintain a global list of threads
+ SHORTLOCK( &glThreadListLock );
+ new->GlobalPrev = NULL; // Protect against bugs
+ new->GlobalNext = gAllThreads;
+ gAllThreads->GlobalPrev = new;
+ gAllThreads = new;
+ SHORTREL( &glThreadListLock );
+
+ return new;
+}
+
+/**
+ * \brief Clone the TCB of the kernel thread
+ */
+tThread *Threads_CloneThreadZero(void)
+{
+ tThread *new;
+
+ // Allocate and duplicate
+ new = malloc(sizeof(tThread));
+ if(new == NULL) {
+ return NULL;
+ }
+ memcpy(new, &gThreadZero, sizeof(tThread));
+
+ new->Process->nThreads ++;
+
+ new->CurCPU = -1;
+ new->Next = NULL;
+ memset( &new->IsLocked, 0, sizeof(new->IsLocked));
+ new->Status = THREAD_STAT_PREINIT;
+ new->RetStatus = 0;
+
+ // Get Thread ID
+ new->TID = giNextTID++;
+ new->Parent = 0;
+
+ // Clone Name
+ new->ThreadName = NULL;
+
+ // Messages are not inherited
+ new->Messages = NULL;
+ new->LastMessage = NULL;
+
+ // Set State
+ new->Remaining = new->Quantum = DEFAULT_QUANTUM;
+ new->Priority = DEFAULT_PRIORITY;
+ new->bInstrTrace = 0;