user_thread #9
@ -1,6 +1,8 @@
|
|||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
|
#include "kernel.h"
|
||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "klibc.h"
|
#include "klibc.h"
|
||||||
|
#include "paging.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
#include "stdarg.h"
|
#include "stdarg.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
@ -110,6 +112,40 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
|
|||||||
ret = uAddrSpaceUnmap(as, uaddr, size);
|
ret = uAddrSpaceUnmap(as, uaddr, size);
|
||||||
break;
|
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:
|
default:
|
||||||
printf("Unknon syscall id %d\n", syscallId);
|
printf("Unknon syscall id %d\n", syscallId);
|
||||||
ret = -ENOENT;
|
ret = -ENOENT;
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#define SYSCALL_ID_BRK 6
|
#define SYSCALL_ID_BRK 6
|
||||||
#define SYSCALL_ID_MMAP 7
|
#define SYSCALL_ID_MMAP 7
|
||||||
#define SYSCALL_ID_MUNMAP 8
|
#define SYSCALL_ID_MUNMAP 8
|
||||||
|
#define SYSCALL_ID_NEW_THREAD 9
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
int syscallExecute(int syscallId, const struct cpu_state *user_ctx);
|
int syscallExecute(int syscallId, const struct cpu_state *user_ctx);
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#define SYSCALL_ID_BRK 6
|
#define SYSCALL_ID_BRK 6
|
||||||
#define SYSCALL_ID_MMAP 7
|
#define SYSCALL_ID_MMAP 7
|
||||||
#define SYSCALL_ID_MUNMAP 8
|
#define SYSCALL_ID_MUNMAP 8
|
||||||
|
#define SYSCALL_ID_NEW_THREAD 9
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
int syscallExecute(int syscallId, const struct cpu_state *user_ctx);
|
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);
|
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 *calloc(size_t nmemb, size_t size);
|
||||||
void *realloc(void *ptr, size_t size);
|
void *realloc(void *ptr, size_t size);
|
||||||
void free(void *ptr);
|
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(" tiny: a tiny C-like interpreter\n");
|
||||||
printf(" mmap: test mmap \n");
|
printf(" mmap: test mmap \n");
|
||||||
printf(" munmap: test munmap \n");
|
printf(" munmap: test munmap \n");
|
||||||
|
printf(" thread: run a user thread\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,8 +119,20 @@ int func_munmap()
|
|||||||
return ret;
|
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)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
@ -156,6 +169,10 @@ int main(int argc, char *argv[])
|
|||||||
func_munmap();
|
func_munmap();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (strcmp(buf, "thread") == 0) {
|
||||||
|
func_thread();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user