+ // 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
+ SHORTLOCK( &glThreadListLock );
+ // Remove from old priority
+ Threads_int_DelFromQueue( &gaActiveThreads[Thread->Priority], Thread );
+ // And add to new
+ Thread->Next = gaActiveThreads[Pri];
+ gaActiveThreads[Pri] = Thread;
+ Thread->Priority = Pri;
+ SHORTREL( &glThreadListLock );
+ #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;
+ int i;
+ 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)
+ new->TGID = new->TID;
+ else
+ new->TGID = cur->TGID;
+
+ // Messages are not inherited
+ new->Messages = NULL;
+ new->LastMessage = NULL;
+
+ // Set State
+ new->Remaining = new->Quantum = cur->Quantum;
+ new->Priority = cur->Priority;
+
+ // Set Signal Handlers
+ new->CurFaultNum = 0;
+ new->FaultHandler = cur->FaultHandler;
+
+ for( i = 0; i < NUM_CFG_ENTRIES; i ++ )
+ {
+ switch(cCONFIG_TYPES[i])
+ {
+ default:
+ new->Config[i] = cur->Config[i];
+ break;
+ case CFGT_HEAPSTR:
+ if(cur->Config[i])
+ new->Config[i] = (Uint) strdup( (void*)cur->Config[i] );
+ else
+ new->Config[i] = 0;
+ break;
+ }
+ }
+
+ // 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;
+ int i;
+
+ // Allocate and duplicate
+ new = malloc(sizeof(tThread));
+ if(new == NULL) {
+ return NULL;
+ }
+ memcpy(new, &gThreadZero, 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 = 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;
+
+ // Set Signal Handlers
+ new->CurFaultNum = 0;
+ new->FaultHandler = 0;
+
+ for( i = 0; i < NUM_CFG_ENTRIES; i ++ )
+ {
+ new->Config[i] = 0;
+ }
+
+ // Maintain a global list of threads
+ SHORTLOCK( &glThreadListLock );
+ new->GlobalPrev = NULL; // Protect against bugs
+ new->GlobalNext = gAllThreads;
+ gAllThreads->GlobalPrev = new;
+ gAllThreads = new;
+ SHORTREL( &glThreadListLock );