Implemented OSThreadCreate system call

This commit is contained in:
Ali Mashtizadeh 2015-01-16 17:57:21 -08:00
parent 114b35bbbc
commit 5a3d86aa7b
8 changed files with 44 additions and 25 deletions

View File

@ -26,7 +26,7 @@ int OSStat(const char *path, struct stat *sb);
int OSReadDir(uint64_t fd, char *buf, size_t length, uint64_t *offset);
// Threads
int OSThreadCreate(uint64_t rip);
int OSThreadCreate(uint64_t rip, uint64_t arg);
int OSThreadExit(uint64_t status);
int OSThreadSleep(uint64_t time);
int OSThreadWait(uint64_t tid);

View File

@ -92,9 +92,9 @@ OSReadDir(uint64_t fd, char *buf, size_t length, uint64_t *offset)
}
int
OSThreadCreate(uint64_t rip)
OSThreadCreate(uint64_t rip, uint64_t arg)
{
return syscall(SYSCALL_THREADCREATE, rip);
return syscall(SYSCALL_THREADCREATE, rip, arg);
}
int

View File

@ -33,6 +33,9 @@
#define MEM_USERSPACE_LEN 0x0000800000000000ULL
#define MEM_USERSPACE_TOP (MEM_USERSPACE_BASE + MEM_USERSPACE_LEN)
#define MEM_USERSPACE_STKBASE 0x0000000070000000ULL
#define MEM_USERSPACE_STKLEN 0x0000000000010000ULL
#define MEM_DIRECTMAP_BASE 0xFFFF800000000000ULL
#define MEM_DIRECTMAP_LEN 0x0000010000000000ULL
#define MEM_XMAP_BASE 0xFFFF810000000000ULL

View File

@ -11,6 +11,7 @@
#include <machine/amd64.h>
#include <machine/amd64op.h>
#include <machine/trap.h>
#include <machine/pmap.h>
extern void ThreadKThreadEntry(TrapFrame *tf);
extern void switchstack(uint64_t *oldrsp, uint64_t rsp);
@ -22,7 +23,8 @@ Thread_InitArch(Thread *thr)
}
void
Thread_SetupKThread(Thread *thr, void (*f)(void *), void *arg)
Thread_SetupKThread(Thread *thr, void (*f)(),
uintptr_t arg1, uintptr_t arg2, uintptr_t arg3)
{
// Initialize stack
uint64_t stacktop = thr->kstack + PGSIZE;
@ -46,30 +48,34 @@ Thread_SetupKThread(Thread *thr, void (*f)(void *), void *arg)
tf->rsp = stacktop;
tf->cs = SEL_KCS;
tf->rip = (uint64_t)f;
tf->rdi = (uint64_t)arg;
tf->rdi = (uint64_t)arg1;
tf->rsi = (uint64_t)arg2;
tf->rdx = (uint64_t)arg3;
tf->rflags = RFLAGS_IF;
}
static void
ThreadEnterUserLevelCB(void *arg)
ThreadEnterUserLevelCB(uintptr_t arg1, uintptr_t arg2, uintptr_t arg3)
{
TrapFrame tf;
memset(&tf, 0, sizeof(tf));
tf.ds = SEL_UDS | 3;
tf.rip = (uint64_t)arg;
tf.rip = (uint64_t)arg1;
tf.cs = SEL_UCS | 3;
tf.rsp = 0x70000000 + PGSIZE;
tf.rsp = (uint64_t)arg2 + MEM_USERSPACE_STKLEN;
tf.ss = SEL_UDS | 3;
tf.rflags = RFLAGS_IF;
tf.rdi = (uint64_t)arg3; /* Userspace Argument */
Trap_Pop(&tf);
}
void
Thread_SetupUThread(Thread *thr, uint64_t rip)
Thread_SetupUThread(Thread *thr, uintptr_t rip, uintptr_t arg)
{
Thread_SetupKThread(thr, ThreadEnterUserLevelCB, (void *)rip);
Thread_SetupKThread(thr, ThreadEnterUserLevelCB, rip,
thr->ustack, arg);
}
extern TaskStateSegment64 TSS[MAX_CPUS];

View File

@ -22,6 +22,7 @@ typedef struct Thread {
ThreadArch arch;
AS *space;
uintptr_t kstack;
uintptr_t ustack;
uint64_t tid;
// Process
struct Process *proc;
@ -43,6 +44,7 @@ typedef struct Thread {
typedef struct Process {
uint64_t pid;
AS *space;
uintptr_t ustackNext; // Next user stack
TAILQ_ENTRY(Process) processList;
// Threads
uint64_t threads;
@ -57,7 +59,7 @@ Thread *Thread_Current();
Process *Thread_CreateProcess();
Thread *Thread_Create(Process *proc);
Thread *Thread_KThreadCreate(void (*f)(void*), void *arg);
Thread *Thread_UThreadCreate(Thread *oldThr, uint64_t rip);
Thread *Thread_UThreadCreate(Thread *oldThr, uint64_t rip, uint64_t arg);
void Thread_SetRunnable(Thread *thr);
void Thread_SetWaiting(Thread *thr);
void Thread_SetZombie(Thread *thr);
@ -73,8 +75,9 @@ void Process_Destroy(Process *proc);
// Platform functions
void Thread_InitArch(Thread *thr);
void Thread_SetupKThread(Thread *thr, void (*f)(void *), void *arg);
void Thread_SetupUThread(Thread *thr, uint64_t rip);
void Thread_SetupKThread(Thread *thr, void (*f)(),
uintptr_t arg1, uintptr_t arg2, uintptr_t arg3);
void Thread_SetupUThread(Thread *thr, uint64_t rip, uint64_t arg);
void Thread_SwitchArch(Thread *oldthr, Thread *newthr);
// Handle Functions

View File

@ -78,8 +78,7 @@ Loader_LoadFirst(Thread *thr, VNode *vn, void *buf, uint64_t len)
}
}
void *stack = PAlloc_AllocPage();
PMap_Map(as, (uint64_t)DMVA2PA(stack), 0x70000000, 1, 0);
PMap_AllocMap(as, MEM_USERSPACE_STKBASE, MEM_USERSPACE_STKLEN, PTE_W);
PMap_LoadAS(as); // Reload CR3
for (i = 0; i < ehdr->e_phnum; i++)
@ -101,9 +100,10 @@ Loader_LoadFirst(Thread *thr, VNode *vn, void *buf, uint64_t len)
tf.ds = SEL_UDS | 3;
tf.rip = ehdr->e_entry;
tf.cs = SEL_UCS | 3;
tf.rsp = 0x70000000 + PGSIZE;
tf.rsp = MEM_USERSPACE_STKBASE + MEM_USERSPACE_STKLEN;
tf.ss = SEL_UDS | 3;
tf.rflags = RFLAGS_IF;
tf.rdi = 0;
Trap_Pop(&tf);
return true;
@ -243,8 +243,7 @@ Loader_Load(Thread *thr, VNode *vn, void *buf, uint64_t len)
}
}
void *stack = PAlloc_AllocPage();
PMap_Map(as, (uint64_t)DMVA2PA(stack), 0x70000000, 1, 0);
PMap_AllocMap(as, MEM_USERSPACE_STKBASE, MEM_USERSPACE_STKLEN, PTE_W);
for (i = 0; i < ehdr->e_phnum; i++)
{
@ -260,7 +259,7 @@ Loader_Load(Thread *thr, VNode *vn, void *buf, uint64_t len)
}
}
Thread_SetupUThread(thr, ehdr->e_entry);
Thread_SetupUThread(thr, ehdr->e_entry, 0);
return true;
}

View File

@ -285,11 +285,11 @@ Syscall_ReadDir(uint64_t fd, char *user_buf, size_t len, uintptr_t user_off)
}
uint64_t
Syscall_ThreadCreate(uint64_t rip)
Syscall_ThreadCreate(uint64_t rip, uint64_t arg)
{
uint64_t threadId;
Thread *curThread = Thread_Current();
Thread *newThread = Thread_UThreadCreate(curThread, rip);
Thread *newThread = Thread_UThreadCreate(curThread, rip, arg);
if (newThread == NULL) {
return -1;
}
@ -386,7 +386,7 @@ Syscall_Entry(uint64_t syscall, uint64_t a1, uint64_t a2,
case SYSCALL_READDIR:
return Syscall_ReadDir(a1, (char *)a2, a3, a4);
case SYSCALL_THREADCREATE:
return Syscall_ThreadCreate(a1);
return Syscall_ThreadCreate(a1, a2);
case SYSCALL_THREADEXIT:
Syscall_ThreadExit(a1);
return 0;

View File

@ -83,6 +83,9 @@ Thread_Create(Process *proc)
if (proc != NULL) {
// XXX: Add to thread list
proc->threads++;
thr->ustack = proc->ustackNext;
proc->ustackNext += MEM_USERSPACE_STKLEN;
}
if ((proc != NULL) && (proc->space != NULL)) {
@ -124,6 +127,7 @@ Thread_CreateProcess()
Slab_Free(&processSlab, proc);
return NULL;
}
proc->ustackNext = MEM_USERSPACE_STKBASE;
Handle_Init(proc);
@ -139,13 +143,13 @@ Thread_KThreadCreate(void (*f)(void *), void *arg)
if (!thr)
return NULL;
Thread_SetupKThread(thr, f, arg);
Thread_SetupKThread(thr, f, (uintptr_t)arg, 0, 0);
return thr;
}
Thread *
Thread_UThreadCreate(Thread *oldThr, uint64_t rip)
Thread_UThreadCreate(Thread *oldThr, uint64_t rip, uint64_t arg)
{
Process *proc = oldThr->proc;
Thread *thr = (Thread *)Slab_Alloc(&threadSlab);
@ -165,10 +169,14 @@ Thread_UThreadCreate(Thread *oldThr, uint64_t rip)
thr->space = oldThr->space;
thr->schedState = SCHED_STATE_NULL;
thr->ustack = proc->ustackNext;
proc->ustackNext += MEM_USERSPACE_STKLEN;
PMap_AllocMap(thr->space, thr->ustack, MEM_USERSPACE_STKLEN, PTE_W);
Thread_InitArch(thr);
// Initialize queue
Thread_SetupUThread(thr, rip);
Thread_SetupUThread(thr, rip, arg);
thr->proc = proc;
proc->threads++;