Bug fixes and code cleanup for thread related code
This commit is contained in:
parent
7aaf5cbc5f
commit
ee3874da77
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user