Bug fixes and code cleanup for thread related code

This commit is contained in:
Ali Mashtizadeh 2015-01-22 13:04:43 -08:00
parent 7aaf5cbc5f
commit ee3874da77
3 changed files with 86 additions and 40 deletions

View File

@ -55,6 +55,8 @@ typedef struct Thread {
typedef struct Process {
uint64_t pid;
AS *space;
Spinlock lock;
uint64_t nextThreadID;
uintptr_t ustackNext; // Next user stack
TAILQ_ENTRY(Process) processList;
uint64_t refCount;

View File

@ -40,6 +40,11 @@ Syscall_Exit(uint64_t status)
{
Thread *cur = Sched_Current();
// Request each thread to exit
// Wait for all threads to exit
// Exit this thread
Sched_SetZombie(cur);
Thread_Release(cur);
Sched_Scheduler();

View File

@ -15,20 +15,21 @@
#include <machine/trap.h>
#include <machine/pmap.h>
Spinlock threadLock;
uint64_t nextProcessID;
uint64_t nextThreadID;
Thread *curProc;
// Special Kernel Process
Process *kernelProcess;
// Scheduler Queues
Spinlock schedLock;
ThreadQueue waitQueue;
ThreadQueue runnableQueue;
Thread *curProc;
// Process List
Spinlock procLock;
uint64_t nextProcessID;
ProcessQueue processList;
// Memory Pools
Slab processSlab;
Slab threadSlab;
@ -38,12 +39,11 @@ void
Thread_Init()
{
nextProcessID = 1;
nextThreadID = 1;
Slab_Init(&processSlab, "Process Objects", sizeof(Process), 16);
Slab_Init(&threadSlab, "Thread Objects", sizeof(Thread), 16);
Spinlock_Init(&threadLock, "Thread Lock");
Spinlock_Init(&procLock, "Process List Lock");
Spinlock_Init(&schedLock, "Scheduler Lock");
TAILQ_INIT(&waitQueue);
@ -93,12 +93,16 @@ Process_Create(const char *title)
}
proc->ustackNext = MEM_USERSPACE_STKBASE;
Spinlock_Init(&proc->lock, "Process Lock");
Semaphore_Init(&proc->zombieSemaphore, 0, "Zombie Semaphore");
TAILQ_INIT(&proc->zombieQueue);
Handle_Init(proc);
Spinlock_Lock(&procLock);
TAILQ_INSERT_TAIL(&processList, proc, processList);
Spinlock_Unlock(&procLock);
return proc;
}
@ -106,12 +110,36 @@ Process_Create(const char *title)
static void
Process_Destroy(Process *proc)
{
Spinlock_Destroy(&proc->lock);
Semaphore_Destroy(&proc->zombieSemaphore);
PMap_DestroyAS(proc->space);
// XXX: Close and destroy handles
Spinlock_Lock(&procLock);
TAILQ_REMOVE(&processList, proc, processList);
Spinlock_Unlock(&procLock);
Slab_Free(&processSlab, proc);
}
Process *
Process_Lookup(uint64_t pid)
{
Process *p;
Process *proc = NULL;
Spinlock_Lock(&procLock);
TAILQ_FOREACH(p, &processList, processList) {
if (p->pid == pid) {
Process_Retain(p);
proc = p;
break;
}
}
Spinlock_Unlock(&procLock);
return proc;
}
void
@ -150,35 +178,25 @@ Thread_Create(Process *proc)
memset(thr, 0, sizeof(*thr));
thr->tid = nextThreadID++;
ASSERT(proc != NULL);
thr->tid = proc->nextThreadID++;
thr->kstack = (uintptr_t)PAlloc_AllocPage();
if (thr->kstack == 0) {
Slab_Free(&threadSlab, thr);
return NULL;
}
Process_Retain(proc);
Spinlock_Lock(&proc->lock);
thr->proc = proc;
if (proc != NULL) {
// XXX: Add to thread list
proc->threads++;
thr->ustack = proc->ustackNext;
proc->ustackNext += MEM_USERSPACE_STKLEN;
Process_Retain(proc);
}
if ((proc != NULL) && (proc->space != NULL)) {
thr->space = proc->space;
} else {
// XXX: for kernel threads
thr->space = PMap_NewAS();
if (thr->space == NULL) {
PAlloc_Release((void *)thr->kstack);
Slab_Free(&threadSlab, thr);
return NULL;
}
}
proc->threads++;
TAILQ_INSERT_TAIL(&proc->threadList, thr, threadList);
thr->space = proc->space;
thr->ustack = proc->ustackNext;
proc->ustackNext += MEM_USERSPACE_STKLEN;
Spinlock_Unlock(&proc->lock);
thr->schedState = SCHED_STATE_NULL;
thr->timerEvt = NULL;
@ -213,7 +231,7 @@ Thread_UThreadCreate(Thread *oldThr, uint64_t rip, uint64_t arg)
memset(thr, 0, sizeof(*thr));
thr->tid = nextThreadID++;
thr->tid = proc->nextThreadID++;
thr->kstack = (uintptr_t)PAlloc_AllocPage();
if (thr->kstack == 0) {
Slab_Free(&threadSlab, thr);
@ -224,18 +242,27 @@ Thread_UThreadCreate(Thread *oldThr, uint64_t rip, uint64_t arg)
thr->schedState = SCHED_STATE_NULL;
thr->refCount = 1;
Spinlock_Lock(&proc->lock);
thr->ustack = proc->ustackNext;
proc->ustackNext += MEM_USERSPACE_STKLEN;
Spinlock_Unlock(&proc->lock);
PMap_AllocMap(thr->space, thr->ustack, MEM_USERSPACE_STKLEN, PTE_W);
// XXX: Check failure
Thread_InitArch(thr);
// Initialize queue
Thread_SetupUThread(thr, rip, arg);
Process_Retain(proc);
Spinlock_Lock(&proc->lock);
thr->proc = proc;
// XXX: Process lock
proc->threads++;
TAILQ_INSERT_TAIL(&proc->threadList, thr, threadList);
Spinlock_Unlock(&proc->lock);
return thr;
}
@ -247,24 +274,34 @@ Thread_Destroy(Thread *thr)
// Free userspace stack
if (proc) {
proc->threads--;
TAILQ_REMOVE(&proc->threadList, thr, threadList);
}
proc->threads--;
TAILQ_REMOVE(&proc->threadList, thr, threadList);
// Free AS
PAlloc_Release((void *)thr->kstack);
Slab_Free(&threadSlab, thr);
// Release process handle
if (proc) {
//Process_Release(thr->proc);
}
Process_Release(thr->proc);
}
Thread *
Thread_Lookup(Process *proc, uint64_t tid)
{
Thread *t;
Thread *thr = NULL;
Spinlock_Lock(&proc->lock);
TAILQ_FOREACH(t, &proc->threadList, threadList) {
if (t->tid == tid) {
Thread_Retain(t);
thr = t;
break;
}
}
Spinlock_Unlock(&proc->lock);
return thr;
}
void
@ -366,10 +403,12 @@ Sched_SetZombie(Thread *thr)
Spinlock_Lock(&schedLock);
thr->schedState = SCHED_STATE_ZOMBIE;
if (thr->proc) {
TAILQ_INSERT_TAIL(&thr->proc->zombieQueue, thr, schedQueue);
} else {
kprintf("ERROR: Thread not associated with process and no zombie queue!\n");
Spinlock_Lock(&thr->proc->lock);
TAILQ_INSERT_TAIL(&thr->proc->zombieQueue, thr, schedQueue);
Spinlock_Unlock(&thr->proc->lock);
if (thr->proc->threads == 1) {
// XXX: Add process to parents zombie list
}
Spinlock_Unlock(&schedLock);