user_thread #9

Merged
mathieu merged 12 commits from user_thread into master 2024-02-28 20:24:14 +01:00
12 changed files with 80 additions and 9 deletions
Showing only changes of commit 0688afa76d - Show all commits

View File

@ -11,6 +11,7 @@ struct process {
char name[PROCESS_NAME_MAX_LENGTH]; char name[PROCESS_NAME_MAX_LENGTH];
int ref; int ref;
int pid; int pid;
int nextTid;
struct uAddrSpace *addrSpace; struct uAddrSpace *addrSpace;
struct thread *thList; struct thread *thList;
@ -48,6 +49,7 @@ struct process *processCreate(char *name)
disable_IRQs(flags); disable_IRQs(flags);
new->pid = nextPid++; new->pid = nextPid++;
new->nextTid = new->pid;
list_add_tail(processList, new); list_add_tail(processList, new);
restore_IRQs(flags); restore_IRQs(flags);
@ -180,3 +182,11 @@ struct uAddrSpace *processGetAddrSpace(struct process *proc){
int processInitHeap(struct process *proc, uaddr_t lastUserAddr){ int processInitHeap(struct process *proc, uaddr_t lastUserAddr){
return uAddrSpaceSetHeap(proc->addrSpace, lastUserAddr, 0); return uAddrSpaceSetHeap(proc->addrSpace, lastUserAddr, 0);
} }
int processGetId(struct process *proc){
return proc->pid;
}
int processGetNextTid(struct process *proc){
return proc->nextTid++;
}

View File

@ -18,3 +18,5 @@ int processRemoveThread(struct thread *th);
struct mmu_context *processGetMMUContext(struct process *th); struct mmu_context *processGetMMUContext(struct process *th);
struct uAddrSpace *processGetAddrSpace(struct process *proc); struct uAddrSpace *processGetAddrSpace(struct process *proc);
int processInitHeap(struct process *proc, uaddr_t lastUserAddr); int processInitHeap(struct process *proc, uaddr_t lastUserAddr);
int processGetId(struct process *proc);
int processGetNextTid(struct process *proc);

View File

@ -113,11 +113,14 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
} }
case SYSCALL_ID_NEW_THREAD: { case SYSCALL_ID_NEW_THREAD: {
struct uAddrSpace *as; struct uAddrSpace *as;
thread_id_t threadIdPtr;
thread_id_t threadId;
uaddr_t funcAddr; uaddr_t funcAddr;
uint32_t arg1, arg2; uint32_t arg1, arg2;
size_t stackSize; size_t stackSize;
ret = syscallGet4args(userCtx, (unsigned int *)&funcAddr, (unsigned int *)&arg1, ret = syscallGet5args(userCtx, (unsigned int *)&threadIdPtr,
(unsigned int *)&funcAddr, (unsigned int *)&arg1,
(unsigned int *)&arg2, (unsigned int *)&stackSize); (unsigned int *)&arg2, (unsigned int *)&stackSize);
if (ret) if (ret)
break; break;
@ -125,6 +128,11 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
ret = -EINVAL; ret = -EINVAL;
break; break;
} }
if (memcpyFromUser((vaddr_t)&threadId, threadIdPtr, sizeof(threadId)) !=
sizeof(threadId)) {
ret = -EFAULT;
break;
}
as = processGetAddrSpace(getCurrentThread()->process); as = processGetAddrSpace(getCurrentThread()->process);
stackSize = ALIGN(stackSize, PAGE_SIZE); stackSize = ALIGN(stackSize, PAGE_SIZE);
@ -142,6 +150,13 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
ret = -ENOMEM; ret = -ENOMEM;
uAddrSpaceUnmap(as, stackAddr, stackSize); uAddrSpaceUnmap(as, stackAddr, stackSize);
} }
threadId = threadGetId(th);
if (memcpyToUser(threadIdPtr, (vaddr_t)&threadId, sizeof(threadId)) !=
sizeof(threadId)) {
ret = -EFAULT;
break;
}
break; break;
} }
@ -156,6 +171,14 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx)
break; break;
} }
case SYSCALL_ID_GETPID: {
ret = processGetId(getCurrentThread()->process);
break;
}
case SYSCALL_ID_GETTID: {
ret = threadGetId(getCurrentThread());
break;
}
default: default:
printf("Unknon syscall id %d\n", syscallId); printf("Unknon syscall id %d\n", syscallId);
ret = -ENOENT; ret = -ENOENT;

View File

@ -13,6 +13,8 @@
#define SYSCALL_ID_MUNMAP 8 #define SYSCALL_ID_MUNMAP 8
#define SYSCALL_ID_NEW_THREAD 9 #define SYSCALL_ID_NEW_THREAD 9
#define SYSCALL_ID_USLEEP 10 #define SYSCALL_ID_USLEEP 10
#define SYSCALL_ID_GETPID 11
#define SYSCALL_ID_GETTID 12
#ifdef __KERNEL__ #ifdef __KERNEL__
int syscallExecute(int syscallId, const struct cpu_state *user_ctx); int syscallExecute(int syscallId, const struct cpu_state *user_ctx);

View File

@ -12,6 +12,12 @@
static struct thread *currentThread; static struct thread *currentThread;
static struct thread *threadWithTimeout; static struct thread *threadWithTimeout;
static thread_id_t nextTid; // This is the TID for kernel thread ONLY
thread_id_t threadGetId(struct thread *th)
{
return th->tid;
}
static void threadPrepareContext(struct thread *th); static void threadPrepareContext(struct thread *th);
@ -84,6 +90,7 @@ struct thread *threadCreate(const char *name, cpu_kstate_function_arg1_t func, v
goto free_mem; goto free_mem;
thread->state = READY; thread->state = READY;
thread->tid = nextTid++;
uint32_t flags; uint32_t flags;
disable_IRQs(flags); disable_IRQs(flags);
list_add_tail(currentThread, thread); list_add_tail(currentThread, thread);
@ -124,6 +131,7 @@ struct thread *threadCreateUser(const char *name, struct process *proc, uaddr_t
goto free_mem; goto free_mem;
thread->state = READY; thread->state = READY;
thread->tid = processGetNextTid(proc);
uint32_t flags; uint32_t flags;
disable_IRQs(flags); disable_IRQs(flags);
list_add_tail(currentThread, thread); list_add_tail(currentThread, thread);

View File

@ -17,8 +17,11 @@ typedef enum {
EXITING EXITING
} thread_state; } thread_state;
typedef unsigned long int thread_id_t;
struct thread { struct thread {
char name[THREAD_NAME_MAX_LENGTH]; char name[THREAD_NAME_MAX_LENGTH];
thread_id_t tid;
struct cpu_state *cpuState; struct cpu_state *cpuState;
thread_state state; thread_state state;
vaddr_t stackAddr; vaddr_t stackAddr;
@ -89,3 +92,4 @@ struct thread *getCurrentThread();
int threadAddThread(struct thread *th); int threadAddThread(struct thread *th);
int threadChangeCurrentContext(struct mmu_context *ctx); int threadChangeCurrentContext(struct mmu_context *ctx);
int threadCount(); int threadCount();
thread_id_t threadGetId(struct thread *th);

View File

@ -13,6 +13,8 @@
#define SYSCALL_ID_MUNMAP 8 #define SYSCALL_ID_MUNMAP 8
#define SYSCALL_ID_NEW_THREAD 9 #define SYSCALL_ID_NEW_THREAD 9
#define SYSCALL_ID_USLEEP 10 #define SYSCALL_ID_USLEEP 10
#define SYSCALL_ID_GETPID 11
#define SYSCALL_ID_GETTID 12
#ifdef __KERNEL__ #ifdef __KERNEL__
int syscallExecute(int syscallId, const struct cpu_state *user_ctx); int syscallExecute(int syscallId, const struct cpu_state *user_ctx);

View File

@ -5,6 +5,7 @@
#include "swintr.h" #include "swintr.h"
#include "sys/mman.h" #include "sys/mman.h"
#include "syscall.h" #include "syscall.h"
#include "thread.h"
#include "unistd.h" #include "unistd.h"
int errno = 0; int errno = 0;
@ -761,12 +762,19 @@ static void thread_runner()
_exit(0); _exit(0);
} }
int new_thread(start_routine *func, void *arg, size_t stackSize) int thread_create(pthread_t *thread, start_routine *func, void *arg, size_t stackSize) {
{ return syscall5(SYSCALL_ID_NEW_THREAD, (unsigned int)thread, (unsigned int)thread_runner, (unsigned int)func,
return syscall4(SYSCALL_ID_NEW_THREAD, (unsigned int)thread_runner, (unsigned int)func,
(unsigned int)arg, stackSize); (unsigned int)arg, stackSize);
} }
int usleep(useconds_t usec) { int usleep(useconds_t usec) {
return syscall1(SYSCALL_ID_USLEEP, (unsigned int)usec); return syscall1(SYSCALL_ID_USLEEP, (unsigned int)usec);
} }
pid_t gettid(void) {
return syscall0(SYSCALL_ID_GETTID);
}
pid_t getpid(void) {
return syscall0(SYSCALL_ID_GETPID);
}

View File

@ -4,6 +4,7 @@
#include "stdint.h" #include "stdint.h"
#include "stddef.h" #include "stddef.h"
#include "minmax.h" #include "minmax.h"
#include "unistd.h"
#define islower(c) (('a' <= (c)) && ((c) <= 'z')) #define islower(c) (('a' <= (c)) && ((c) <= 'z'))
#define isupper(c) (('A' <= (c)) && ((c) <= 'Z')) #define isupper(c) (('A' <= (c)) && ((c) <= 'Z'))
@ -63,6 +64,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);
pid_t gettid(void);
pid_t getpid(void);
typedef void *(start_routine)(void *);
int new_thread(start_routine *func, void *arg, size_t stackSize);

View File

@ -3,6 +3,7 @@
#include "stdarg.h" #include "stdarg.h"
#include "stddef.h" #include "stddef.h"
#include "sys/mman.h" #include "sys/mman.h"
#include "thread.h"
#include "tiny.h" #include "tiny.h"
#include "unistd.h" #include "unistd.h"
@ -122,14 +123,15 @@ int func_munmap()
static void *print_hello(void *arg) { static void *print_hello(void *arg) {
(void)arg; (void)arg;
printf("Hello World from thread\n"); printf("Hello World from thread %d\n", gettid());
usleep(100); usleep(100);
return NULL; return NULL;
} }
int func_thread() { int func_thread() {
new_thread(print_hello, NULL, 4096); pthread_t id;
thread_create(&id, print_hello, NULL, 4096);
return 0; return 0;
} }
@ -138,6 +140,7 @@ int main(int argc, char *argv[]) {
(void)argc; (void)argc;
(void)argv; (void)argv;
char buf[64]; char buf[64];
assert(getpid() == gettid());
printf("Shell starting... type \"help\" for help\n"); printf("Shell starting... type \"help\" for help\n");
while (1) { while (1) {
printf(">"); printf(">");

6
userspace/thread.h Normal file
View File

@ -0,0 +1,6 @@
#pragma once
#include <stddef.h>
typedef unsigned long int pthread_t;
typedef void *(start_routine)(void *);
int thread_create(pthread_t *thread, start_routine *func, void *arg, size_t stackSize);

View File

@ -2,3 +2,5 @@
typedef unsigned int useconds_t; typedef unsigned int useconds_t;
int usleep(useconds_t usec); int usleep(useconds_t usec);
typedef int pid_t;