#define SCHED_RR_SIM 2 // Single Queue Round Robin
#define SCHED_RR_PRI 3 // Multi Queue Round Robin
// Set scheduler type
-#define SCHEDULER_TYPE SCHED_RR_PRI
+#define SCHEDULER_TYPE SCHED_LOTTERY
// === CONSTANTS ===
#define DEFAULT_QUANTUM 10
extern tThread *Proc_GetCurThread(void);
extern int Proc_Clone(Uint *Err, Uint Flags);
extern void Proc_CallFaultHandler(tThread *Thread);
+extern int GetCPUNum(void);
// === PROTOTYPES ===
void Threads_Init(void);
- int Threads_SetName(char *NewName);
+ int Threads_SetName(const char *NewName);
char *Threads_GetName(int ID);
-void Threads_SetTickets(tThread *Thread, int Num);
+void Threads_SetPriority(tThread *Thread, int Pri);
tThread *Threads_CloneTCB(Uint *Err, Uint Flags);
int Threads_WaitTID(int TID, int *status);
tThread *Threads_GetThread(Uint TID);
}
/**
- * \fn void Threads_SetName(char *NewName)
+ * \fn void Threads_SetName(const char *NewName)
* \brief Sets the current thread's name
* \param NewName New name for the thread
* \return Boolean Failure
*/
-int Threads_SetName(char *NewName)
+int Threads_SetName(const char *NewName)
{
tThread *cur = Proc_GetCurThread();
char *oldname = cur->ThreadName;
{
SHORTLOCK( &glThreadListLock );
+ if( Thread->Status == THREAD_STAT_ACTIVE ) {
+ tThread *cur = Proc_GetCurThread();
+ Warning("WTF, CPU%i %p (%i %s) is adding %p (%i %s) when it is active",
+ GetCPUNum(), cur, cur->TID, cur->ThreadName, Thread, Thread->TID, Thread->ThreadName);
+ }
+
// Set state
Thread->Status = THREAD_STAT_ACTIVE;
Thread->CurCPU = -1;
#if SCHEDULER_TYPE == SCHED_LOTTERY
giFreeTickets += caiTICKET_COUNTS[ Thread->Priority ];
# if DEBUG_TRACE_TICKETS
- Log("Threads_AddActive: %p %i (%s) added, new giFreeTickets = %i",
- Thread, Thread->TID, Thread->ThreadName, giFreeTickets);
+ Log("Threads_AddActive: CPU%i %p %i (%s) added, new giFreeTickets = %i",
+ GetCPUNum(), Thread, Thread->TID, Thread->ThreadName, giFreeTickets);
# endif
#endif
return NULL;
}
+ ret->Next = NULL;
ret->Remaining = 0;
ret->CurCPU = -1;
// no need to decrement tickets, scheduler did it for us
#if SCHEDULER_TYPE == SCHED_LOTTERY && DEBUG_TRACE_TICKETS
- Log("Threads_RemActive: %p %i (%s) removed, giFreeTickets = %i",
- ret, ret->TID, ret->ThreadName, giFreeTickets);
+ Log("Threads_RemActive: CPU%i %p %i (%s) removed, giFreeTickets = %i",
+ GetCPUNum(), ret, ret->TID, ret->ThreadName, giFreeTickets);
#endif
SHORTREL( &glThreadListLock );
for(thread=gActiveThreads;thread;thread=thread->Next)
#endif
{
- Log(" %i (%i) - %s (CPU %i)",
- thread->TID, thread->TGID, thread->ThreadName, thread->CurCPU);
+ Log(" %p %i (%i) - %s (CPU %i)",
+ thread, thread->TID, thread->TGID, thread->ThreadName, thread->CurCPU);
if(thread->Status != THREAD_STAT_ACTIVE)
Log(" ERROR State (%i) != THREAD_STAT_ACTIVE (%i)", thread->Status, THREAD_STAT_ACTIVE);
Log(" Priority %i, Quantum %i", thread->Priority, thread->Quantum);
Log("All Threads:");
for(thread=gAllThreads;thread;thread=thread->GlobalNext)
{
- Log(" %i (%i) - %s (CPU %i)",
- thread->TID, thread->TGID, thread->ThreadName, thread->CurCPU);
- Log(" State %i", thread->Status);
+ Log(" %p %i (%i) - %s (CPU %i)",
+ thread, thread->TID, thread->TGID, thread->ThreadName, thread->CurCPU);
+ Log(" State %i (%s)", thread->Status, casTHREAD_STAT[thread->Status]);
+ switch(thread->Status)
+ {
+ case THREAD_STAT_MUTEXSLEEP:
+ Log(" Mutex Pointer: %p", thread->WaitPointer);
+ break;
+ case THREAD_STAT_ZOMBIE:
+ Log(" Return Status: %i", thread->RetStatus);
+ break;
+ default: break;
+ }
Log(" Priority %i, Quantum %i", thread->Priority, thread->Quantum);
Log(" KStack 0x%x", thread->KernelStack);
}
thread = gDeleteThreads->Next;
if( IS_LOCKED(&gDeleteThreads->IsLocked) ) { // Only free if structure is unused
// Set to dead
- gDeleteThreads->Status = THREAD_STAT_DEAD;
+ gDeleteThreads->Status = THREAD_STAT_BURIED;
// Free name
if( IsHeap(gDeleteThreads->ThreadName) )
free(gDeleteThreads->ThreadName);
SHORTLOCK( &glThreadListLock );
// - Remove from active list
us = Threads_RemActive();
+ us->Next = NULL;
// - Mark as sleeping
- us->Status = THREAD_STAT_OFFSLEEP;
+ us->Status = THREAD_STAT_MUTEXSLEEP;
+ us->WaitPointer = Mutex;
// - Add to waiting
if(Mutex->LastWaiting) {
Mutex->Waiting = us;
Mutex->LastWaiting = us;
}
+ #if 0
+ {
+ int i = 0;
+ tThread *t;
+ for( t = Mutex->Waiting; t; t = t->Next, i++ )
+ Log("[%i] (tMutex)%p->Waiting[%i] = %p (%i %s)", us->TID, Mutex, i,
+ t, t->TID, t->ThreadName);
+ }
+ #endif
+
SHORTREL( &glThreadListLock );
SHORTREL( &Mutex->Protector );
- while(us->Status == THREAD_STAT_OFFSLEEP) Threads_Yield();
+ while(us->Status == THREAD_STAT_MUTEXSLEEP) Threads_Yield();
// We're only woken when we get the lock
+ us->WaitPointer = NULL;
}
// Ooh, let's take it!
else {
Mutex->Owner = us;
SHORTREL( &Mutex->Protector );
}
+
+ #if 0
+ extern tMutex glPhysAlloc;
+ if( Mutex != &glPhysAlloc )
+ LogF("Mutex %p taken by %i %p\n", Mutex, us->TID, __builtin_return_address(0));
+ #endif
}
/**
Mutex->Owner = NULL;
}
SHORTREL( &Mutex->Protector );
+
+ #if 0
+ extern tMutex glPhysAlloc;
+ if( Mutex != &glPhysAlloc )
+ LogF("Mutex %p released by %i %p\n", Mutex, Threads_GetTID(), __builtin_return_address(0));
+ #endif
}
/**