/*
- * Acess2
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
* threads.c
* - Common Thread Control
*/
int Threads_SetUID(Uint *Errno, tUID ID);
int Threads_SetGID(Uint *Errno, tUID ID);
#endif
+void Threads_int_DumpThread(tThread *thread);
void Threads_Dump(void);
void Threads_DumpActive(void);
Log_Debug("Threads", ".KernelStack = %i", offsetof(tThread, KernelStack));
// Create Initial Task
-// #if SCHEDULER_TYPE == SCHED_RR_PRI
-// gaActiveThreads[gThreadZero.Priority].Head = &gThreadZero;
-// gaActiveThreads[gThreadZero.Priority].Tail = &gThreadZero;
-// #else
-// gActiveThreads.Head = &gThreadZero;
-// gActiveThreads.Tail = &gThreadZero;
-// #endif
-
gAllThreads = &gThreadZero;
giNumActiveThreads = 1;
gThreadZero.Process = &gProcessZero;
Proc_ClearThread(Thread);
Thread->Process->nThreads --;
+
+ if( Thread->Process->FirstThread == Thread )
+ {
+ Thread->Process->FirstThread = Thread->ProcessNext;
+ }
+ else
+ {
+ tThread *prev = Thread->Process->FirstThread;
+ while(prev && prev->ProcessNext != Thread)
+ prev = prev->ProcessNext;
+ if( !prev )
+ Log_Error("Threads", "Thread %p(%i %s) is not on the process's list",
+ Thread, Thread->TID, Thread->ThreadName
+ );
+ else
+ prev->ProcessNext = Thread->ProcessNext;
+ }
+
+ // If the final thread is being terminated, clean up the process
if( Thread->Process->nThreads == 0 )
{
tProcess *proc = Thread->Process;
if( IsHeap(oldname) ) free( oldname );
cur->ThreadName = strdup(NewName);
- Log_Debug("Threads", "Thread renamed to '%s'", NewName);
+// Log_Debug("Threads", "Thread renamed to '%s'", NewName);
return 0;
}
new->Process = malloc( sizeof(struct sProcess) );
newproc = new->Process;
newproc->PID = new->TID;
+ if( Flags & CLONE_PGID )
+ newproc->PGID = oldproc->PGID;
+ else
+ newproc->PGID = newproc->PID;
newproc->UID = oldproc->UID;
newproc->GID = oldproc->GID;
newproc->MaxFD = oldproc->MaxFD;
newproc->nThreads = 1;
// Reference all handles in the VFS
VFS_ReferenceUserHandles();
+
+ newproc->FirstThread = new;
+ new->ProcessNext = NULL;
}
else {
new->Process->nThreads ++;
+ new->Process = cur->Process;
+ // TODO: Locking
+ new->ProcessNext = new->Process->FirstThread;
+ new->Process->FirstThread = new;
}
// Messages are not inherited
tThread *thread;
// Search global list
- for(thread = gAllThreads;
- thread;
- thread = thread->GlobalNext)
+ for( thread = gAllThreads; thread; thread = thread->GlobalNext )
{
if(thread->TID == TID)
return thread;
}
- Log("Unable to find TID %i on main list\n", TID);
+ Log_Notice("Threads", "Unable to find TID %i on main list\n", TID);
return NULL;
}
return -EALREADY;
case THREAD_STAT_SLEEPING:
- SHORTLOCK( &glThreadListLock );
// Remove from sleeping queue
+ SHORTLOCK( &glThreadListLock );
Threads_int_DelFromQueue(&gSleepingThreads, Thread);
-
SHORTREL( &glThreadListLock );
+
Threads_AddActive( Thread );
#if DEBUG_TRACE_STATE
return -ENOTIMPL;
default:
- Warning("Threads_Wake - Unknown process status (%i)\n", Thread->Status);
+ Log_Warning("Threads", "Threads_Wake - Unknown process status (%i)", Thread->Status);
return -EINTERNAL;
}
}
*/
tThread *Threads_RemActive(void)
{
- #if 0
- tThread *ret = Proc_GetCurThread();
-
- if( !IS_LOCKED(&glThreadListLock) ) {
- Log_KernelPanic("Threads", "Threads_RemActive called without lock held");
- return NULL;
- }
-
- // Delete from active queue
- #if SCHEDULER_TYPE == SCHED_RR_PRI
- if( !Threads_int_DelFromQueue(&gaActiveThreads[ret->Priority], ret) )
- #else
- if( !Threads_int_DelFromQueue(&gActiveThreads, ret) )
- #endif
- {
- Log_Warning("Threads", "Current thread %p(%i %s) is not on active queue",
- ret, ret->TID, ret->ThreadName
- );
- return NULL;
- }
-
- ret->Next = NULL;
- ret->Remaining = 0;
-
giNumActiveThreads --;
- // no need to decrement tickets, scheduler did it for us
-
- #if SCHEDULER_TYPE == SCHED_LOTTERY && DEBUG_TRACE_TICKETS
- Log("CPU%i %p (%i %s) removed, giFreeTickets = %i [nc]",
- GetCPUNum(), ret, ret->TID, ret->ThreadName, giFreeTickets);
- #endif
-
- return ret;
- #else
return Proc_GetCurThread();
- #endif
}
/**
}
// --- Process Structure Access Functions ---
+tPGID Threads_GetPGID(void)
+{
+ return Proc_GetCurThread()->Process->PGID;
+}
tPID Threads_GetPID(void)
{
return Proc_GetCurThread()->Process->PID;
}
// ---
+void Threads_int_DumpThread(tThread *thread)
+{
+ Log(" %p %i (%i) - %s (CPU %i) - %i (%s)",
+ thread, thread->TID, thread->Process->PID, thread->ThreadName, thread->CurCPU,
+ thread->Status, casTHREAD_STAT[thread->Status]
+ );
+ switch(thread->Status)
+ {
+ case THREAD_STAT_MUTEXSLEEP:
+ Log(" Mutex Pointer: %p", thread->WaitPointer);
+ break;
+ case THREAD_STAT_SEMAPHORESLEEP:
+ Log(" Semaphore Pointer: %p", thread->WaitPointer);
+ Log(" Semaphore Name: %s:%s",
+ ((tSemaphore*)thread->WaitPointer)->ModName,
+ ((tSemaphore*)thread->WaitPointer)->Name
+ );
+ 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 %p", thread->KernelStack);
+ if( thread->bInstrTrace )
+ Log(" Tracing Enabled");
+ Proc_DumpThreadCPUState(thread);
+}
+
/**
* \fn void Threads_Dump(void)
*/
#endif
for(thread=list->Head;thread;thread=thread->Next)
{
- Log(" %p %i (%i) - %s (CPU %i)",
- thread, thread->TID, thread->Process->PID, thread->ThreadName, thread->CurCPU);
+ Threads_int_DumpThread(thread);
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(" KStack 0x%x", thread->KernelStack);
- if( thread->bInstrTrace )
- Log(" Tracing Enabled");
- Proc_DumpThreadCPUState(thread);
}
#if SCHEDULER_TYPE == SCHED_RR_PRI
Log("All Threads:");
for(thread=gAllThreads;thread;thread=thread->GlobalNext)
{
- Log(" %p %i (%i) - %s (CPU %i)",
- thread, thread->TID, thread->Process->PID, 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_SEMAPHORESLEEP:
- Log(" Semaphore Pointer: %p", thread->WaitPointer);
- Log(" Semaphore Name: %s:%s",
- ((tSemaphore*)thread->WaitPointer)->ModName,
- ((tSemaphore*)thread->WaitPointer)->Name
- );
- 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);
- if( thread->bInstrTrace )
- Log(" Tracing Enabled");
- Proc_DumpThreadCPUState(thread);
+ Threads_int_DumpThread(thread);
}
}