Implemented OSThreadExit and a nonblocking OSThreadWait
This commit is contained in:
parent
db7bb93d56
commit
1160570250
@ -31,6 +31,7 @@ typedef struct Thread {
|
||||
int schedState;
|
||||
TAILQ_ENTRY(Thread) schedQueue;
|
||||
TimerEvent *timerEvt; // Timer event for wakeups
|
||||
uintptr_t exitValue;
|
||||
// Statistics
|
||||
uint64_t ctxSwitches;
|
||||
uint64_t userTime;
|
||||
@ -48,6 +49,7 @@ typedef struct Process {
|
||||
TAILQ_ENTRY(Process) processList;
|
||||
// Threads
|
||||
uint64_t threads;
|
||||
TAILQ_HEAD(ZombieQueueHead, Thread) zombieQueue;
|
||||
// Handles
|
||||
uint64_t nextFD;
|
||||
TAILQ_HEAD(HandleQHead, Handle) handles[PROCESS_HANDLE_SLOTS];
|
||||
@ -64,6 +66,7 @@ void Thread_SetRunnable(Thread *thr);
|
||||
void Thread_SetWaiting(Thread *thr);
|
||||
void Thread_SetZombie(Thread *thr);
|
||||
void Thread_Destroy(Thread *thr);
|
||||
uint64_t Thread_Wait(Thread *thr, uint64_t tid);
|
||||
void Thread_Switch(Thread *oldthr, Thread *newthr);
|
||||
void Thread_Scheduler();
|
||||
void Thread_ProcDump(Process *proc);
|
||||
|
@ -305,6 +305,9 @@ Syscall_ThreadExit(uint64_t status)
|
||||
{
|
||||
Thread *cur = Thread_Current();
|
||||
|
||||
// Encode this like POSIX
|
||||
cur->exitValue = status;
|
||||
|
||||
Thread_SetZombie(cur);
|
||||
Thread_Scheduler();
|
||||
|
||||
@ -343,9 +346,9 @@ Syscall_ThreadSleep(uint64_t time)
|
||||
uint64_t
|
||||
Syscall_ThreadWait(uint64_t tid)
|
||||
{
|
||||
// XXX: Support waiting
|
||||
Thread *cur = Thread_Current();
|
||||
|
||||
return 0;
|
||||
return Thread_Wait(cur, tid);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
|
@ -121,6 +121,7 @@ Thread_CreateProcess()
|
||||
|
||||
proc->pid = nextProcessID++;
|
||||
proc->threads = 0;
|
||||
TAILQ_INIT(&proc->zombieQueue);
|
||||
|
||||
proc->space = PMap_NewAS();
|
||||
if (proc->space == NULL) {
|
||||
@ -219,7 +220,12 @@ Thread_SetZombie(Thread *thr)
|
||||
Spinlock_Lock(&threadLock);
|
||||
|
||||
thr->schedState = SCHED_STATE_ZOMBIE;
|
||||
// XXX: Add to wait queue
|
||||
if (thr->proc) {
|
||||
TAILQ_INSERT_TAIL(&thr->proc->zombieQueue, thr, schedQueue);
|
||||
kprintf("ZOMBIEQUEUE\n");
|
||||
} else {
|
||||
kprintf("ERROR: Thread not associated with process and no zombie queue!\n");
|
||||
}
|
||||
|
||||
Spinlock_Unlock(&threadLock);
|
||||
}
|
||||
@ -229,11 +235,52 @@ Thread_Destroy(Thread *thr)
|
||||
{
|
||||
// Remove from queue
|
||||
|
||||
// Free userspace stack
|
||||
|
||||
if (thr->proc) {
|
||||
thr->proc->threads--;
|
||||
}
|
||||
|
||||
// Free AS
|
||||
PAlloc_Release((void *)thr->kstack);
|
||||
Slab_Free(&threadSlab, thr);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
Thread_Wait(Thread *thr, uint64_t tid)
|
||||
{
|
||||
Thread *t;
|
||||
uint64_t status;
|
||||
|
||||
ASSERT(thr->proc != NULL);
|
||||
|
||||
Thread_Dump(thr);
|
||||
|
||||
if (tid == 0) {
|
||||
t = TAILQ_FIRST(&thr->proc->zombieQueue);
|
||||
if (!t) {
|
||||
kprintf("EMPTY %llx\n", t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TAILQ_REMOVE(&thr->proc->zombieQueue, t, schedQueue);
|
||||
status = t->exitValue;
|
||||
Thread_Destroy(t);
|
||||
return status;
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(t, &thr->proc->zombieQueue, schedQueue) {
|
||||
if (t->tid == tid) {
|
||||
TAILQ_REMOVE(&thr->proc->zombieQueue, t, schedQueue);
|
||||
status = t->exitValue;
|
||||
Thread_Destroy(t);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Thread_Switch(Thread *oldthr, Thread *newthr)
|
||||
{
|
||||
@ -256,8 +303,12 @@ Thread_Scheduler()
|
||||
if (!next) {
|
||||
/*
|
||||
* There may be no other runnable processes on this core. This is a
|
||||
* good opportunity to migrate threads.
|
||||
* good opportunity to migrate threads. We should never hit this case
|
||||
* once the OS is up and running because of the idle threads, but just
|
||||
* in case we should assert that we never return to a zombie or waiting
|
||||
* thread.
|
||||
*/
|
||||
ASSERT(curProc->schedState == SCHED_STATE_RUNNING);
|
||||
Spinlock_Unlock(&threadLock);
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user