diff --git a/include/errno.h b/include/errno.h index a87c0f4..3c6db71 100644 --- a/include/errno.h +++ b/include/errno.h @@ -11,6 +11,7 @@ #define ENOTDIR 0xBAD7 #define ENAMETOOLONG 0xBAD8 #define ENOSYS 0xBAD9 +#define EAGAIN 0xBADA #endif /* __ERRNO_H__ */ diff --git a/include/pthread.h b/include/pthread.h index 29e0bdf..7433701 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -2,12 +2,12 @@ #ifndef __PTHREAD_H__ #define __PTHREAD_H__ -typedef uint64_t pthread_t; -typedef uint64_t pthread_attr_t; -typedef uint64_t pthread_barrier_t; -typedef uint64_t pthread_barrierattr_t; -typedef uint64_t pthread_mutex_t; -typedef uint64_t pthread_mutexattr_t; +typedef struct pthread *pthread_t; +typedef struct pthread_attr *pthread_attr_t; +typedef struct pthread_barrier *pthread_barrier_t; +typedef struct pthread_barrierattr *pthread_barrierattr_t; +typedef struct pthread_mutex *pthread_mutex_t; +typedef struct pthread_mutexattr *pthread_mutexattr_t; pthread_t pthread_self(void); int pthread_create(pthread_t *thread, const pthread_attr_t *attr, diff --git a/lib/libc/posix/pthread.c b/lib/libc/posix/pthread.c index a32af77..8b89873 100644 --- a/lib/libc/posix/pthread.c +++ b/lib/libc/posix/pthread.c @@ -1,34 +1,101 @@ #include +#include +#include #include +#include #include #include +#include + +struct pthread_attr { + uint64_t _unused; +}; + +struct pthread { + uint64_t tid; + int errno; + + // Initialization + void *(*entry)(void *); + void *arg; + + // Termination + void *result; +}; pthread_t pthread_self(void) { + // XXX Implement + return NULL; +} + +void +pthreadCreateHelper(void *arg) +{ + struct pthread *thr = (struct pthread *)arg; + + OSThreadExit((uint64_t)(thr->entry)(thr->arg)); } int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { + uint64_t status; + struct pthread *thr; + + thr = malloc(sizeof(*thr)); + if (!thr) { + return EAGAIN; + } + + memset(thr, 0, sizeof(*thr)); + + thr->entry = start_routine; + thr->arg = arg; + + status = OSThreadCreate((uintptr_t)&pthreadCreateHelper, (uint64_t)thr); + if (SYSCALL_ERRCODE(status) != 0) { + free(thr); + return SYSCALL_ERRCODE(status); + } + + thr->tid = SYSCALL_VALUE(status); + + *thread = thr; + + return 0; } void pthread_exit(void *value_ptr) { - OSThreadExit(value_ptr); + struct pthread *thr = pthread_self(); + + thr->result = value_ptr; + + OSThreadExit(0); } int pthread_join(pthread_t thread, void **value_ptr) { - uint64_t value = OSThreadWait(thread); + struct pthread *thr = thread; + uint64_t status = OSThreadWait(thr->tid); + if (status != 0) { + return status; + } - *value_ptr = (void *)value; + *value_ptr = (void *)thr->result; + + // Cleanup + free(thr); + + return 0; } void