Begin refactoring to support both threads and processes
This commit is contained in:
parent
c74592a3ba
commit
9d9f301bdd
@ -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
8
sys/include/loader.h
Normal 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__ */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user