diff --git a/core/process.c b/core/process.c index 6d5b0a3..7024366 100644 --- a/core/process.c +++ b/core/process.c @@ -11,6 +11,7 @@ struct process { char name[PROCESS_NAME_MAX_LENGTH]; int ref; int pid; + int nextTid; struct uAddrSpace *addrSpace; struct thread *thList; @@ -47,7 +48,8 @@ struct process *processCreate(char *name) new->ref = 1; disable_IRQs(flags); - new->pid = nextPid++; + new->pid = nextPid++; + new->nextTid = new->pid; list_add_tail(processList, new); restore_IRQs(flags); @@ -180,3 +182,11 @@ struct uAddrSpace *processGetAddrSpace(struct process *proc){ int processInitHeap(struct process *proc, uaddr_t lastUserAddr){ return uAddrSpaceSetHeap(proc->addrSpace, lastUserAddr, 0); } + +int processGetId(struct process *proc){ + return proc->pid; +} + +int processGetNextTid(struct process *proc){ + return proc->nextTid++; +} diff --git a/core/process.h b/core/process.h index f5935f7..172aeb4 100644 --- a/core/process.h +++ b/core/process.h @@ -18,3 +18,5 @@ int processRemoveThread(struct thread *th); struct mmu_context *processGetMMUContext(struct process *th); struct uAddrSpace *processGetAddrSpace(struct process *proc); int processInitHeap(struct process *proc, uaddr_t lastUserAddr); +int processGetId(struct process *proc); +int processGetNextTid(struct process *proc); diff --git a/core/syscall.c b/core/syscall.c index 5a5151f..283841a 100644 --- a/core/syscall.c +++ b/core/syscall.c @@ -113,11 +113,14 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx) } case SYSCALL_ID_NEW_THREAD: { struct uAddrSpace *as; + thread_id_t threadIdPtr; + thread_id_t threadId; uaddr_t funcAddr; uint32_t arg1, arg2; 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); if (ret) break; @@ -125,6 +128,11 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx) ret = -EINVAL; break; } + if (memcpyFromUser((vaddr_t)&threadId, threadIdPtr, sizeof(threadId)) != + sizeof(threadId)) { + ret = -EFAULT; + break; + } as = processGetAddrSpace(getCurrentThread()->process); stackSize = ALIGN(stackSize, PAGE_SIZE); @@ -142,6 +150,13 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx) ret = -ENOMEM; uAddrSpaceUnmap(as, stackAddr, stackSize); } + threadId = threadGetId(th); + + if (memcpyToUser(threadIdPtr, (vaddr_t)&threadId, sizeof(threadId)) != + sizeof(threadId)) { + ret = -EFAULT; + break; + } break; } @@ -156,6 +171,14 @@ int syscallExecute(int syscallId, const struct cpu_state *userCtx) break; } + case SYSCALL_ID_GETPID: { + ret = processGetId(getCurrentThread()->process); + break; + } + case SYSCALL_ID_GETTID: { + ret = threadGetId(getCurrentThread()); + break; + } default: printf("Unknon syscall id %d\n", syscallId); ret = -ENOENT; diff --git a/core/syscall.h b/core/syscall.h index 53cfa05..ca46a20 100644 --- a/core/syscall.h +++ b/core/syscall.h @@ -13,6 +13,8 @@ #define SYSCALL_ID_MUNMAP 8 #define SYSCALL_ID_NEW_THREAD 9 #define SYSCALL_ID_USLEEP 10 +#define SYSCALL_ID_GETPID 11 +#define SYSCALL_ID_GETTID 12 #ifdef __KERNEL__ int syscallExecute(int syscallId, const struct cpu_state *user_ctx); diff --git a/core/thread.c b/core/thread.c index cbb55af..d450392 100644 --- a/core/thread.c +++ b/core/thread.c @@ -12,6 +12,12 @@ static struct thread *currentThread; 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); @@ -84,6 +90,7 @@ struct thread *threadCreate(const char *name, cpu_kstate_function_arg1_t func, v goto free_mem; thread->state = READY; + thread->tid = nextTid++; uint32_t flags; disable_IRQs(flags); list_add_tail(currentThread, thread); @@ -124,6 +131,7 @@ struct thread *threadCreateUser(const char *name, struct process *proc, uaddr_t goto free_mem; thread->state = READY; + thread->tid = processGetNextTid(proc); uint32_t flags; disable_IRQs(flags); list_add_tail(currentThread, thread); diff --git a/core/thread.h b/core/thread.h index 6da8cd7..84a44dd 100644 --- a/core/thread.h +++ b/core/thread.h @@ -17,8 +17,11 @@ typedef enum { EXITING } thread_state; +typedef unsigned long int thread_id_t; + struct thread { char name[THREAD_NAME_MAX_LENGTH]; + thread_id_t tid; struct cpu_state *cpuState; thread_state state; vaddr_t stackAddr; @@ -89,3 +92,4 @@ struct thread *getCurrentThread(); int threadAddThread(struct thread *th); int threadChangeCurrentContext(struct mmu_context *ctx); int threadCount(); +thread_id_t threadGetId(struct thread *th); diff --git a/userspace/kernel/syscall.h b/userspace/kernel/syscall.h index 53cfa05..ca46a20 100644 --- a/userspace/kernel/syscall.h +++ b/userspace/kernel/syscall.h @@ -13,6 +13,8 @@ #define SYSCALL_ID_MUNMAP 8 #define SYSCALL_ID_NEW_THREAD 9 #define SYSCALL_ID_USLEEP 10 +#define SYSCALL_ID_GETPID 11 +#define SYSCALL_ID_GETTID 12 #ifdef __KERNEL__ int syscallExecute(int syscallId, const struct cpu_state *user_ctx); diff --git a/userspace/libc.c b/userspace/libc.c index fa793c2..7d5f071 100644 --- a/userspace/libc.c +++ b/userspace/libc.c @@ -5,6 +5,7 @@ #include "swintr.h" #include "sys/mman.h" #include "syscall.h" +#include "thread.h" #include "unistd.h" int errno = 0; @@ -761,12 +762,19 @@ static void thread_runner() _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, +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, (unsigned int)arg, stackSize); } int usleep(useconds_t 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); +} diff --git a/userspace/libc.h b/userspace/libc.h index 12bcf9d..9a12ba2 100644 --- a/userspace/libc.h +++ b/userspace/libc.h @@ -4,6 +4,7 @@ #include "stdint.h" #include "stddef.h" #include "minmax.h" +#include "unistd.h" #define islower(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 *realloc(void *ptr, size_t size); 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); diff --git a/userspace/main_user.c b/userspace/main_user.c index 88128fd..92dc49b 100644 --- a/userspace/main_user.c +++ b/userspace/main_user.c @@ -3,6 +3,7 @@ #include "stdarg.h" #include "stddef.h" #include "sys/mman.h" +#include "thread.h" #include "tiny.h" #include "unistd.h" @@ -122,14 +123,15 @@ int func_munmap() static void *print_hello(void *arg) { (void)arg; - printf("Hello World from thread\n"); + printf("Hello World from thread %d\n", gettid()); usleep(100); return NULL; } int func_thread() { - new_thread(print_hello, NULL, 4096); + pthread_t id; + thread_create(&id, print_hello, NULL, 4096); return 0; } @@ -138,6 +140,7 @@ int main(int argc, char *argv[]) { (void)argc; (void)argv; char buf[64]; + assert(getpid() == gettid()); printf("Shell starting... type \"help\" for help\n"); while (1) { printf(">"); diff --git a/userspace/thread.h b/userspace/thread.h new file mode 100644 index 0000000..a3a78f6 --- /dev/null +++ b/userspace/thread.h @@ -0,0 +1,6 @@ +#pragma once +#include + +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); diff --git a/userspace/unistd.h b/userspace/unistd.h index 7d7da70..e9675d3 100644 --- a/userspace/unistd.h +++ b/userspace/unistd.h @@ -2,3 +2,5 @@ typedef unsigned int useconds_t; int usleep(useconds_t usec); + +typedef int pid_t;