user_thread #9
@ -1,6 +1,8 @@
|
||||
#include "syscall.h"
|
||||
#include "kernel.h"
|
||||
#include "keyboard.h"
|
||||
#include "klibc.h"
|
||||
#include "paging.h"
|
||||
#include "process.h"
|
||||
#include "stdarg.h"
|
||||
#include "thread.h"
|
||||
@ -43,17 +45,17 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
|
||||
printf("Got 5args from userspace %d %d %d %d %d\n", arg1, arg2, arg3, arg4, arg5);
|
||||
break;
|
||||
}
|
||||
case SYSCALL_ID_BRK:{
|
||||
case SYSCALL_ID_BRK: {
|
||||
|
||||
struct uAddrSpace *as;
|
||||
uaddr_t newHeapTop;
|
||||
|
||||
as = processGetAddrSpace(getCurrentThread()->process);
|
||||
as = processGetAddrSpace(getCurrentThread()->process);
|
||||
ret = syscallGet1arg(userCtx, (unsigned int *)&newHeapTop);
|
||||
if (ret != 0)
|
||||
break;
|
||||
threadChangeCurrentContext(uAddrSpaceGetMMUContext(as));
|
||||
//TODO : what if *newHeapTop raise page fault?
|
||||
// TODO : what if *newHeapTop raise page fault?
|
||||
ret = sysBrk(as, newHeapTop);
|
||||
threadChangeCurrentContext(NULL);
|
||||
break;
|
||||
@ -110,6 +112,40 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
|
||||
ret = uAddrSpaceUnmap(as, uaddr, size);
|
||||
break;
|
||||
}
|
||||
case SYSCALL_ID_NEW_THREAD: {
|
||||
struct uAddrSpace *as;
|
||||
uaddr_t funcAddr;
|
||||
uint32_t arg1, arg2;
|
||||
size_t stackSize;
|
||||
|
||||
ret = syscallGet4args(userCtx, (unsigned int *)&funcAddr, (unsigned int *)&arg1,
|
||||
(unsigned int *)&arg2, (unsigned int *)&stackSize);
|
||||
if (ret)
|
||||
break;
|
||||
if (stackSize <= 0) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
as = processGetAddrSpace(getCurrentThread()->process);
|
||||
stackSize = ALIGN(stackSize, PAGE_SIZE);
|
||||
|
||||
uaddr_t stackAddr = 0;
|
||||
ret = zeroMmap(as, &stackAddr, stackSize, PAGING_MEM_READ | PAGING_MEM_WRITE, 0);
|
||||
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
struct thread *th = threadCreateUser(NULL, getCurrentThread()->process, funcAddr,
|
||||
arg1, arg2, stackAddr + stackSize);
|
||||
|
||||
if (th == NULL) {
|
||||
ret = -ENOMEM;
|
||||
uAddrSpaceUnmap(as, stackAddr, stackSize);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printf("Unknon syscall id %d\n", syscallId);
|
||||
ret = -ENOENT;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#define SYSCALL_ID_BRK 6
|
||||
#define SYSCALL_ID_MMAP 7
|
||||
#define SYSCALL_ID_MUNMAP 8
|
||||
#define SYSCALL_ID_NEW_THREAD 9
|
||||
|
||||
#ifdef __KERNEL__
|
||||
int syscallExecute(int syscallId, const struct cpu_state *user_ctx);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#define SYSCALL_ID_BRK 6
|
||||
#define SYSCALL_ID_MMAP 7
|
||||
#define SYSCALL_ID_MUNMAP 8
|
||||
#define SYSCALL_ID_NEW_THREAD 9
|
||||
|
||||
#ifdef __KERNEL__
|
||||
int syscallExecute(int syscallId, const struct cpu_state *user_ctx);
|
||||
|
@ -745,3 +745,23 @@ int munmap(void *addr, size_t len)
|
||||
|
||||
return syscall2(SYSCALL_ID_MUNMAP, (unsigned int)addr, len);
|
||||
}
|
||||
|
||||
/* As when a new thread is run, the params are passed by register (See cpu_ustate_init), use
|
||||
* this function to simplify new thread usage*/
|
||||
static void thread_runner()
|
||||
{
|
||||
register unsigned long int reg_arg1 asm("%eax");
|
||||
register unsigned long int reg_arg2 asm("%ebx");
|
||||
|
||||
start_routine *func = (start_routine *)reg_arg1;
|
||||
void *arg = (void *)reg_arg2;
|
||||
|
||||
func(arg);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
int new_thread(start_routine *func, void *arg, size_t stackSize)
|
||||
{
|
||||
return syscall4(SYSCALL_ID_NEW_THREAD, (unsigned int)thread_runner, (unsigned int)func,
|
||||
(unsigned int)arg, stackSize);
|
||||
}
|
||||
|
@ -63,3 +63,6 @@ void *malloc(size_t size);
|
||||
void *calloc(size_t nmemb, size_t size);
|
||||
void *realloc(void *ptr, size_t size);
|
||||
void free(void *ptr);
|
||||
|
||||
typedef void *(start_routine)(void *);
|
||||
int new_thread(start_routine *func, void *arg, size_t stackSize);
|
||||
|
@ -15,6 +15,7 @@ int func_help()
|
||||
printf(" tiny: a tiny C-like interpreter\n");
|
||||
printf(" mmap: test mmap \n");
|
||||
printf(" munmap: test munmap \n");
|
||||
printf(" thread: run a user thread\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -118,8 +119,20 @@ int func_munmap()
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
static void *print_hello(void *arg) {
|
||||
(void)arg;
|
||||
printf("Hello World from thread\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int func_thread() {
|
||||
new_thread(print_hello, NULL, 4096);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
char buf[64];
|
||||
@ -156,6 +169,10 @@ int main(int argc, char *argv[])
|
||||
func_munmap();
|
||||
continue;
|
||||
}
|
||||
if (strcmp(buf, "thread") == 0) {
|
||||
func_thread();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user