Begin refactoring to support both threads and processes

This commit is contained in:
Ali Mashtizadeh 2015-01-14 14:28:43 -08:00
parent c74592a3ba
commit 9d9f301bdd
7 changed files with 216 additions and 54 deletions

View File

@ -15,7 +15,7 @@ typedef struct Handle Handle;
typedef struct Handle {
uint64_t fd; // FD Number
uint64_t type; // Type
uint64_t threadId; // Thread ID
uint64_t processId; // Process ID
VNode *vnode; // File VNode
TAILQ_ENTRY(Handle) handleList; // Hash table
int (*read)(Handle *, void *, uint64_t, uint64_t); // Read

8
sys/include/loader.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef __SYS_LOADER_H__
#define __SYS_LOADER_H__
bool Loader_Load(Thread *thr, VNode *vn, void *buf, uint64_t len);
#endif /* __SYS_LOADER_H__ */

View File

@ -17,13 +17,14 @@ typedef struct Thread Thread;
#define SCHED_STATE_WAITING 3
#define SCHED_STATE_ZOMBIE 4
#define THREAD_HANDLE_SLOTS 128
typedef struct Thread {
ThreadArch arch;
AS *space;
uintptr_t kstack;
uint64_t tid;
// Process
struct Process *proc;
// XXX: process list
// Scheduler
int schedState;
TAILQ_ENTRY(Thread) schedQueue;
@ -32,20 +33,38 @@ typedef struct Thread {
uint64_t userTime;
uint64_t kernTime;
uint64_t waitTime;
// Handles
uint64_t nextFD;
TAILQ_HEAD(HandleQHead, Handle) handles[THREAD_HANDLE_SLOTS];
} Thread;
#define PROCESS_HANDLE_SLOTS 128
typedef struct Process {
uint64_t pid;
AS *space;
// Threads
uint64_t threads;
// Handles
uint64_t nextFD;
TAILQ_HEAD(HandleQHead, Handle) handles[PROCESS_HANDLE_SLOTS];
} Process;
// Thread functions
void Thread_Init();
Thread *Thread_Current();
Thread *Thread_Create();
Process *Thread_CreateProcess();
Thread *Thread_Create(Process *proc);
Thread *Thread_KThreadCreate(void (*f)(void*), void *arg);
Thread *Thread_UThreadCreate(Thread *oldThr, uint64_t rip);
void Thread_SetRunnable(Thread *thr);
void Thread_SetZombie(Thread *thr);
void Thread_Destroy(Thread *thr);
void Thread_Switch(Thread *oldthr, Thread *newthr);
void Thread_Scheduler();
void Thread_ProcDump(Process *proc);
void Thread_Dump(Thread *thr);
// Process functions
Process *Process_Create();
void Process_Destroy(Process *proc);
// Platform functions
void Thread_InitArch(Thread *thr);
@ -54,10 +73,10 @@ void Thread_SetupUThread(Thread *thr, uint64_t rip);
void Thread_SwitchArch(Thread *oldthr, Thread *newthr);
// Handle Functions
void Handle_Init(Thread *thr);
uint64_t Handle_Add(Thread *thr, Handle *handle);
void Handle_Remove(Thread *thr, Handle *handle);
Handle *Handle_Lookup(Thread *thr, uint64_t fd);
void Handle_Init(Process *proc);
uint64_t Handle_Add(Process *proc, Handle *handle);
void Handle_Remove(Process *proc, Handle *handle);
Handle *Handle_Lookup(Process *proc, uint64_t fd);
// CopyIn/CopyOut Functions
int CopyIn(uintptr_t fromuser, void *tokernel, uintptr_t len);

View File

@ -20,46 +20,46 @@ Handle_GlobalInit()
DEFINE_SLAB(Handle, &handleSlab);
void
Handle_Init(Thread *thr)
Handle_Init(Process *proc)
{
int i;
for (i = 0; i < THREAD_HANDLE_SLOTS; i++) {
TAILQ_INIT(&thr->handles[i]);
for (i = 0; i < PROCESS_HANDLE_SLOTS; i++) {
TAILQ_INIT(&proc->handles[i]);
}
}
uint64_t
Handle_Add(Thread *thr, Handle *handle)
Handle_Add(Process *proc, Handle *handle)
{
int slot;
handle->fd = thr->nextFD;
thr->nextFD++;
handle->threadId = thr->tid;
handle->fd = proc->nextFD;
proc->nextFD++;
handle->processId = proc->pid;
slot = handle->fd % THREAD_HANDLE_SLOTS;
slot = handle->fd % PROCESS_HANDLE_SLOTS;
TAILQ_INSERT_HEAD(&thr->handles[slot], handle, handleList);
TAILQ_INSERT_HEAD(&proc->handles[slot], handle, handleList);
return handle->fd;
}
void
Handle_Remove(Thread *thr, Handle *handle)
Handle_Remove(Process *proc, Handle *handle)
{
int slot = handle->fd % THREAD_HANDLE_SLOTS;
int slot = handle->fd % PROCESS_HANDLE_SLOTS;
TAILQ_REMOVE(&thr->handles[slot], handle, handleList);
TAILQ_REMOVE(&proc->handles[slot], handle, handleList);
}
Handle *
Handle_Lookup(Thread *thr, uint64_t fd)
Handle_Lookup(Process *proc, uint64_t fd)
{
int slot = fd % THREAD_HANDLE_SLOTS;
int slot = fd % PROCESS_HANDLE_SLOTS;
Handle *handle;
TAILQ_FOREACH(handle, &thr->handles[slot], handleList) {
TAILQ_FOREACH(handle, &proc->handles[slot], handleList) {
if (handle->fd == fd)
return handle;
}

View File

@ -15,6 +15,7 @@
#include <machine/pmap.h>
#include <sys/thread.h>
#include <sys/spinlock.h>
#include <sys/loader.h>
#include <sys/vfs.h>
@ -133,11 +134,11 @@ Loader_LoadInit()
// Open stdin/out/err
Handle *handle = Console_OpenHandle();
Handle_Add(thr, handle);
Handle_Add(thr->proc, handle);
handle = Console_OpenHandle();
Handle_Add(thr, handle);
Handle_Add(thr->proc, handle);
handle = Console_OpenHandle();
Handle_Add(thr, handle);
Handle_Add(thr->proc, handle);
Loader_LoadFirst(thr, init, pg, 1024);

View File

@ -9,6 +9,7 @@
#include <sys/kmem.h>
#include <sys/ktime.h>
#include <sys/thread.h>
#include <sys/loader.h>
#include <sys/syscall.h>
#include <sys/disk.h>
#include <sys/vfs.h>
@ -43,6 +44,7 @@ Syscall_Spawn(uint64_t user_path)
char path[512];
void *pg;
VNode *file;
Process *proc;
Thread *thr;
// XXX: Use CopyInStr
@ -77,15 +79,16 @@ Syscall_Spawn(uint64_t user_path)
return status;
}
thr = Thread_Create();
proc = Thread_CreateProcess();
thr = Thread_Create(proc);
Log(syscall, "SPAWN %lx\n", thr);
Handle *handle = Console_OpenHandle();
Handle_Add(thr, handle);
Handle_Add(proc, handle);
handle = Console_OpenHandle();
Handle_Add(thr, handle);
Handle_Add(proc, handle);
handle = Console_OpenHandle();
Handle_Add(thr, handle);
Handle_Add(proc, handle);
Loader_Load(thr, file, pg, 1024);
@ -147,7 +150,7 @@ uint64_t
Syscall_Read(uint64_t fd, uint64_t addr, uint64_t off, uint64_t length)
{
Thread *cur = Thread_Current();
Handle *handle = Handle_Lookup(cur, fd);
Handle *handle = Handle_Lookup(cur->proc, fd);
if (handle == NULL)
return -EBADF;
@ -159,7 +162,7 @@ uint64_t
Syscall_Write(uint64_t fd, uint64_t addr, uint64_t off, uint64_t length)
{
Thread *cur = Thread_Current();
Handle *handle = Handle_Lookup(cur, fd);
Handle *handle = Handle_Lookup(cur->proc, fd);
if (handle == NULL)
return -EBADF;
@ -171,7 +174,7 @@ uint64_t
Syscall_Flush(uint64_t fd)
{
Thread *cur = Thread_Current();
Handle *handle = Handle_Lookup(cur, fd);
Handle *handle = Handle_Lookup(cur->proc, fd);
if (handle == NULL)
return -EBADF;
@ -197,7 +200,7 @@ Syscall_Open(uint64_t user_path, uint64_t flags)
if (strncmp("/dev/", path, 5) == 0) {
if (strcmp("/dev/console", path) == 0) {
Handle *handle = Console_OpenHandle();
return Handle_Add(cur, handle);
return Handle_Add(cur->proc, handle);
}
return -ENOENT;
@ -208,14 +211,14 @@ Syscall_Open(uint64_t user_path, uint64_t flags)
if (status != 0)
return status;
return Handle_Add(cur, handle);
return Handle_Add(cur->proc, handle);
}
uint64_t
Syscall_Close(uint64_t fd)
{
Thread *cur = Thread_Current();
Handle *handle = Handle_Lookup(cur, fd);
Handle *handle = Handle_Lookup(cur->proc, fd);
if (handle == NULL)
return -EBADF;
@ -256,7 +259,7 @@ Syscall_ReadDir(uint64_t fd, char *user_buf, size_t len, uintptr_t user_off)
{
int status, rstatus;
Thread *cur = Thread_Current();
Handle *handle = Handle_Lookup(cur, fd);
Handle *handle = Handle_Lookup(cur->proc, fd);
uint64_t offset;
if (handle == NULL)
@ -280,6 +283,34 @@ Syscall_ReadDir(uint64_t fd, char *user_buf, size_t len, uintptr_t user_off)
return rstatus;
}
uint64_t
Syscall_ThreadCreate(uint64_t rip)
{
uint64_t threadId;
Thread *curThread = Thread_Current();
Thread *newThread = Thread_UThreadCreate(curThread, rip);
if (newThread == NULL) {
return -1;
}
threadId = newThread->tid;
Thread_SetRunnable(newThread);
return threadId;
}
void
Syscall_ThreadExit(uint64_t status)
{
Thread *cur = Thread_Current();
Thread_SetZombie(cur);
Thread_Scheduler();
// Should not return
Panic("Returned to exited thread!\n");
}
uint64_t
Syscall_ThreadSleep(uint64_t time)
{
@ -325,7 +356,12 @@ Syscall_Entry(uint64_t syscall, uint64_t a1, uint64_t a2,
case SYSCALL_STAT:
return Syscall_Stat(a1, a2);
case SYSCALL_READDIR:
return Syscall_ReadDir(a1, a2, a3, a4);
return Syscall_ReadDir(a1, (char *)a2, a3, a4);
case SYSCALL_THREADCREATE:
return Syscall_ThreadCreate(a1);
case SYSCALL_THREADEXIT:
Syscall_ThreadExit(a1);
return 0;
case SYSCALL_THREADSLEEP:
return Syscall_ThreadSleep(a1);
default:

View File

@ -15,10 +15,13 @@
#include <machine/pmap.h>
Spinlock threadLock;
uint64_t nextProcessID;
uint64_t nextThreadID;
Thread *curProc;
// Runnable Queue
TAILQ_HEAD(ThreadQueueHead, Thread) threadQueue;
Slab processSlab;
Slab threadSlab;
void Handle_GlobalInit();
@ -26,12 +29,15 @@ void Handle_GlobalInit();
void
Thread_Init()
{
nextProcessID = 1;
nextThreadID = 1;
Slab_Init(&processSlab, "Process Objects", sizeof(Process), 16);
Slab_Init(&threadSlab, "Thread Objects", sizeof(Thread), 16);
// Create an thread object for current context
curProc = Thread_Create();
Process *proc = Thread_CreateProcess();
curProc = Thread_Create(proc);
curProc->schedState = SCHED_STATE_RUNNING;
Spinlock_Init(&threadLock, "Thread Lock");
@ -48,7 +54,7 @@ Thread_Current()
}
Thread *
Thread_Create()
Thread_Create(Process *proc)
{
Thread *thr = (Thread *)Slab_Alloc(&threadSlab);
@ -64,17 +70,26 @@ Thread_Create()
return NULL;
}
thr->space = PMap_NewAS();
if (thr->space == NULL) {
PAlloc_Release((void *)thr->kstack);
Slab_Free(&threadSlab, thr);
return NULL;
thr->proc = proc;
if (proc != NULL) {
// XXX: Add to thread list
proc->threads++;
}
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;
}
}
thr->schedState = SCHED_STATE_NULL;
thr->nextFD = 0;
Handle_Init(thr);
Thread_InitArch(thr);
// Initialize queue
@ -82,10 +97,34 @@ Thread_Create()
return thr;
}
Process *
Thread_CreateProcess()
{
Process *proc = (Process *)Slab_Alloc(&processSlab);
if (!proc)
return NULL;
memset(proc, 0, sizeof(*proc));
proc->pid = nextProcessID++;
proc->threads = 0;
proc->space = PMap_NewAS();
if (proc->space == NULL) {
Slab_Free(&processSlab, proc);
return NULL;
}
Handle_Init(proc);
return proc;
}
Thread *
Thread_KThreadCreate(void (*f)(void *), void *arg)
{
Thread *thr = Thread_Create();
Thread *thr = Thread_Create(NULL);
if (!thr)
return NULL;
@ -94,6 +133,39 @@ Thread_KThreadCreate(void (*f)(void *), void *arg)
return thr;
}
Thread *
Thread_UThreadCreate(Thread *oldThr, uint64_t rip)
{
Process *proc = oldThr->proc;
Thread *thr = (Thread *)Slab_Alloc(&threadSlab);
if (!thr)
return NULL;
memset(thr, 0, sizeof(*thr));
thr->tid = nextThreadID++;
thr->kstack = (uintptr_t)PAlloc_AllocPage();
if (thr->kstack == 0) {
Slab_Free(&threadSlab, thr);
return NULL;
}
thr->space = oldThr->space;
thr->schedState = SCHED_STATE_NULL;
Thread_InitArch(thr);
// Initialize queue
Thread_SetupUThread(thr, rip);
thr->proc = proc;
proc->threads++;
// XXX: Add to proc thread list
return thr;
}
void
Thread_SetRunnable(Thread *thr)
{
@ -174,6 +246,32 @@ ThreadKThreadEntry(TrapFrame *tf)
Trap_Pop(tf);
}
void
Thread_ProcDump(Process *proc)
{
kprintf("pid %llu\n", proc->pid);
kprintf("space %016llx\n", proc->space);
kprintf("threads %llu\n", proc->threads);
kprintf("nextFD %llu\n", proc->nextFD);
}
void
Thread_Dump(Thread *thr)
{
// Thread_DumpArch(thr)
kprintf("space %016llx\n", thr->space);
kprintf("kstack %016llx\n", thr->kstack);
kprintf("tid %llu\n", thr->tid);
kprintf("state %d\n", thr->schedState);
kprintf("ctxswtch %llu\n", thr->ctxSwitches);
kprintf("utime %llu\n", thr->userTime);
kprintf("ktime %llu\n", thr->kernTime);
kprintf("wtime %llu\n", thr->waitTime);
if (thr->proc) {
Thread_ProcDump(thr->proc);
}
}
void
Debug_Threads(int argc, const char *argv[])
{
@ -181,10 +279,10 @@ Debug_Threads(int argc, const char *argv[])
//Spinlock_Lock(&threadLock);
kprintf("Current: %016llx %d\n", curProc, curProc->ctxSwitches);
kprintf("Current: %d(%016llx) %d\n", curProc->tid, curProc, curProc->ctxSwitches);
TAILQ_FOREACH(thr, &threadQueue, schedQueue)
{
kprintf("Thread: %016llx %d\n", thr, thr->ctxSwitches);
kprintf("Thread: %d(%016llx) %d\n", curProc->tid, thr, thr->ctxSwitches);
}
//Spinlock_Unlock(&threadLock);