From c957f1ddca0b1c5a4da4035b18412952ef76f568 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sat, 31 May 2025 23:34:26 +0300 Subject: [PATCH] LibC: Cleanup pthread code and add some pthread_attr functions errno, pthread cleanup and pthread id are now stored in uthread. This allows using these without TLS --- kernel/kernel/Process.cpp | 9 +- userspace/libraries/LibC/errno.cpp | 9 +- userspace/libraries/LibC/include/aio.h | 3 +- .../LibC/include/bits/pthread_types.h | 44 ---- .../LibC/include/bits/types/locale_t.h | 4 +- .../LibC/include/bits/types/pthread_attr_t.h | 25 ++ .../LibC/include/bits/types/pthread_t.h | 17 ++ .../LibC/include/bits/types/pthread_types.h | 72 ++++++ .../LibC/include/bits/types/sched_param.h | 23 ++ .../LibC/include/bits/types/timeval.h | 4 +- userspace/libraries/LibC/include/mqueue.h | 3 +- userspace/libraries/LibC/include/pthread.h | 42 +++- userspace/libraries/LibC/include/sched.h | 9 +- userspace/libraries/LibC/include/signal.h | 5 +- userspace/libraries/LibC/include/sys/types.h | 9 - userspace/libraries/LibC/pthread.cpp | 225 ++++++++++++++---- userspace/libraries/LibC/unistd.cpp | 11 +- 17 files changed, 368 insertions(+), 146 deletions(-) delete mode 100644 userspace/libraries/LibC/include/bits/pthread_types.h create mode 100644 userspace/libraries/LibC/include/bits/types/pthread_attr_t.h create mode 100644 userspace/libraries/LibC/include/bits/types/pthread_t.h create mode 100644 userspace/libraries/LibC/include/bits/types/pthread_types.h create mode 100644 userspace/libraries/LibC/include/bits/types/sched_param.h diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index f2d00581ee..1c2d5a48a7 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -350,6 +350,9 @@ namespace Kernel .self = reinterpret_cast(region->vaddr() + master_size), .master_tls_addr = reinterpret_cast(master_addr), .master_tls_size = master_size, + .cleanup_stack = nullptr, + .id = -1, + .errno_ = 0, }; const uintptr_t dtv[2] { 1, region->vaddr() }; @@ -2468,11 +2471,7 @@ namespace Kernel if (attr) { TRY(validate_pointer_access(attr, sizeof(*attr), false)); - if (*attr) - { - dwarnln("pthread attr not supported"); - return BAN::Error::from_errno(ENOTSUP); - } + dwarnln("TODO: ignoring thread attr"); } LockGuard _(m_process_lock); diff --git a/userspace/libraries/LibC/errno.cpp b/userspace/libraries/LibC/errno.cpp index b5682b6ebd..6f2a668f6a 100644 --- a/userspace/libraries/LibC/errno.cpp +++ b/userspace/libraries/LibC/errno.cpp @@ -1,12 +1,9 @@ #include +#include -#if __disable_thread_local_storage -static int s_errno = 0; -#else -static thread_local int s_errno = 0; -#endif +extern uthread* _get_uthread(); int* __errno_location() { - return &s_errno; + return &_get_uthread()->errno_; } diff --git a/userspace/libraries/LibC/include/aio.h b/userspace/libraries/LibC/include/aio.h index cb46113dfb..eb8ca233a8 100644 --- a/userspace/libraries/LibC/include/aio.h +++ b/userspace/libraries/LibC/include/aio.h @@ -12,11 +12,12 @@ __BEGIN_DECLS #include #define __need_off_t -#define __need_pthread_attr_t #define __need_size_t #define __need_ssize_t #include +#include + struct aiocb { int aio_fildes; /* File descriptor. */ diff --git a/userspace/libraries/LibC/include/bits/pthread_types.h b/userspace/libraries/LibC/include/bits/pthread_types.h deleted file mode 100644 index 8d1dfa4dbf..0000000000 --- a/userspace/libraries/LibC/include/bits/pthread_types.h +++ /dev/null @@ -1,44 +0,0 @@ -// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_types.h.html - -#include - -__BEGIN_DECLS - -#if !defined(__pthread_attr_t_defined) && (defined(__need_all_types) || defined(__need_pthread_attr_t) || defined(__need_pthread_types)) - #define __pthread_attr_t_defined 1 - typedef int pthread_attr_t; -#endif -#undef __need_pthread_attr_t - -#if !defined(__pthread_t_defined) && (defined(__need_all_types) || defined(__need_pthread_t) || defined(__need_pthread_types)) - #define __pthread_t_defined 1 - typedef pid_t pthread_t; -#endif -#undef __need_pthread_t - -#if !defined(__pthread_types_defined) && (defined(__need_all_types) || defined(__need_pthread_types)) -#define __pthread_types_defined 1 - -typedef int pthread_once_t; - -typedef unsigned pthread_key_t; - -typedef pthread_t pthread_spinlock_t; - -typedef struct { int type; int shared; } pthread_mutexattr_t; -typedef struct { pthread_mutexattr_t attr; pthread_t locker; unsigned lock_depth; } pthread_mutex_t; - -typedef struct { int shared; } pthread_barrierattr_t; -typedef struct { pthread_barrierattr_t attr; unsigned target; unsigned waiting; } pthread_barrier_t; - -typedef struct { int clock; int shared; } pthread_condattr_t; -struct _pthread_cond_block { struct _pthread_cond_block* next; int signaled; }; -typedef struct { pthread_condattr_t attr; pthread_spinlock_t lock; struct _pthread_cond_block* block_list; } pthread_cond_t; - -typedef struct { int shared; } pthread_rwlockattr_t; -typedef struct { pthread_rwlockattr_t attr; unsigned lockers; unsigned writers; } pthread_rwlock_t; - -#endif -#undef __need_pthread_types - -__END_DECLS diff --git a/userspace/libraries/LibC/include/bits/types/locale_t.h b/userspace/libraries/LibC/include/bits/types/locale_t.h index 5be9a9c693..1adfe74948 100644 --- a/userspace/libraries/LibC/include/bits/types/locale_t.h +++ b/userspace/libraries/LibC/include/bits/types/locale_t.h @@ -1,5 +1,5 @@ -#ifndef _BITS_LOCALE_T_H -#define _BITS_LOCALE_T_H 1 +#ifndef _BITS_TYPES_LOCALE_T_H +#define _BITS_TYPES_LOCALE_T_H 1 // https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/locale.h.html diff --git a/userspace/libraries/LibC/include/bits/types/pthread_attr_t.h b/userspace/libraries/LibC/include/bits/types/pthread_attr_t.h new file mode 100644 index 0000000000..84c1c108cf --- /dev/null +++ b/userspace/libraries/LibC/include/bits/types/pthread_attr_t.h @@ -0,0 +1,25 @@ +#ifndef _BITS_TYPES_PTHREAD_ATTR_T_H +#define _BITS_TYPES_PTHREAD_ATTR_T_H 1 + +// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html + +#include + +__BEGIN_DECLS + +#include + +typedef struct +{ + int inheritsched; + struct sched_param schedparam; + int schedpolicy; + int detachstate; + int scope; + size_t stacksize; + size_t guardsize; +} pthread_attr_t; + +__END_DECLS + +#endif diff --git a/userspace/libraries/LibC/include/bits/types/pthread_t.h b/userspace/libraries/LibC/include/bits/types/pthread_t.h new file mode 100644 index 0000000000..9ad1510568 --- /dev/null +++ b/userspace/libraries/LibC/include/bits/types/pthread_t.h @@ -0,0 +1,17 @@ +#ifndef _BITS_TYPES_PTHREAD_T_H +#define _BITS_TYPES_PTHREAD_T_H 1 + +// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html + +#include + +__BEGIN_DECLS + +#define __need_pid_t +#include + +typedef pid_t pthread_t; + +__END_DECLS + +#endif diff --git a/userspace/libraries/LibC/include/bits/types/pthread_types.h b/userspace/libraries/LibC/include/bits/types/pthread_types.h new file mode 100644 index 0000000000..e538b24c01 --- /dev/null +++ b/userspace/libraries/LibC/include/bits/types/pthread_types.h @@ -0,0 +1,72 @@ +#ifndef _BITS_TYPES_PTHREAD_TYPES_H +#define _BITS_TYPES_PTHREAD_TYPES_H 1 + +// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html + +#include + +__BEGIN_DECLS + +#include +#include + +typedef int pthread_once_t; + +typedef unsigned pthread_key_t; + +typedef pthread_t pthread_spinlock_t; + +typedef struct +{ + int type; + int shared; +} pthread_mutexattr_t; +typedef struct +{ + pthread_mutexattr_t attr; + pthread_t locker; + unsigned lock_depth; +} pthread_mutex_t; + +typedef struct +{ + int shared; +} pthread_barrierattr_t; +typedef struct +{ + pthread_barrierattr_t attr; + unsigned target; + unsigned waiting; +} pthread_barrier_t; + +typedef struct +{ + int clock; + int shared; +} pthread_condattr_t; +struct _pthread_cond_block +{ + struct _pthread_cond_block* next; + int signaled; +}; +typedef struct +{ + pthread_condattr_t attr; + pthread_spinlock_t lock; + struct _pthread_cond_block* block_list; +} pthread_cond_t; + +typedef struct +{ + int shared; +} pthread_rwlockattr_t; +typedef struct +{ + pthread_rwlockattr_t attr; + unsigned lockers; + unsigned writers; +} pthread_rwlock_t; + +__END_DECLS + +#endif diff --git a/userspace/libraries/LibC/include/bits/types/sched_param.h b/userspace/libraries/LibC/include/bits/types/sched_param.h new file mode 100644 index 0000000000..a66f2dac69 --- /dev/null +++ b/userspace/libraries/LibC/include/bits/types/sched_param.h @@ -0,0 +1,23 @@ +#ifndef _BITS_TYPES_SCHED_PARAM_H +#define _BITS_TYPES_SCHED_PARAM_H 1 + +// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sched.h.html + +#include + +__BEGIN_DECLS + +#include + +struct sched_param +{ + int sched_priority; /* Process or thread execution scheduling priority. */ + int sched_ss_low_priority; /* Low scheduling priority for sporadic server. */ + struct timespec sched_ss_repl_period; /* Replenishment period for sporadic server. */ + struct timespec sched_ss_init_budget; /* Initial budget for sporadic server. */ + int sched_ss_max_repl; /* Maximum pending replenishments for sporadic server. */ +}; + +__END_DECLS + +#endif diff --git a/userspace/libraries/LibC/include/bits/types/timeval.h b/userspace/libraries/LibC/include/bits/types/timeval.h index a54b145be2..4bd1435b70 100644 --- a/userspace/libraries/LibC/include/bits/types/timeval.h +++ b/userspace/libraries/LibC/include/bits/types/timeval.h @@ -1,5 +1,5 @@ -#ifndef _BITS_TIMEVAL_H -#define _BITS_TIMEVAL_H 1 +#ifndef _BITS_TYPES_TIMEVAL_H +#define _BITS_TYPES_TIMEVAL_H 1 #include diff --git a/userspace/libraries/LibC/include/mqueue.h b/userspace/libraries/LibC/include/mqueue.h index 5d96826b42..e75a37dcdd 100644 --- a/userspace/libraries/LibC/include/mqueue.h +++ b/userspace/libraries/LibC/include/mqueue.h @@ -10,11 +10,12 @@ __BEGIN_DECLS #include #include -#define __need_pthread_attr_t #define __need_size_t #define __need_ssize_t #include +#include + typedef int mqd_t; struct mq_attr diff --git a/userspace/libraries/LibC/include/pthread.h b/userspace/libraries/LibC/include/pthread.h index 2f4600a851..bab9d0da2d 100644 --- a/userspace/libraries/LibC/include/pthread.h +++ b/userspace/libraries/LibC/include/pthread.h @@ -13,29 +13,45 @@ __BEGIN_DECLS #define __need_size_t #define __need_clockid_t -#define __need_pthread_types #include +#include + +struct _pthread_cleanup_t +{ + void (*routine)(void*); + void* arg; + struct _pthread_cleanup_t* next; +}; + struct uthread { struct uthread* self; void* master_tls_addr; size_t master_tls_size; + struct _pthread_cleanup_t* cleanup_stack; + pthread_t id; + int errno_; uintptr_t dtv[]; }; -#define PTHREAD_CANCEL_ASYNCHRONOUS 2 -#define PTHREAD_CANCEL_ENABLE 3 -#define PTHREAD_CANCEL_DEFERRED 4 -#define PTHREAD_CANCEL_DISABLE 5 -#define PTHREAD_CANCELED 6 -#define PTHREAD_EXPLICIT_SCHED 9 -#define PTHREAD_INHERIT_SCHED 10 -#define PTHREAD_PRIO_INHERIT 18 -#define PTHREAD_PRIO_NONE 19 -#define PTHREAD_PRIO_PROTECT 20 -#define PTHREAD_SCOPE_PROCESS 23 -#define PTHREAD_SCOPE_SYSTEM 24 +#define PTHREAD_CANCELED 1 + +#define PTHREAD_CANCEL_ASYNCHRONOUS 1 +#define PTHREAD_CANCEL_DEFERRED 0 + +#define PTHREAD_CANCEL_DISABLE 0 +#define PTHREAD_CANCEL_ENABLE 1 + +#define PTHREAD_PRIO_INHERIT 1 +#define PTHREAD_PRIO_NONE 0 +#define PTHREAD_PRIO_PROTECT 2 + +#define PTHREAD_EXPLICIT_SCHED 1 +#define PTHREAD_INHERIT_SCHED 0 + +#define PTHREAD_SCOPE_PROCESS 1 +#define PTHREAD_SCOPE_SYSTEM 0 #define PTHREAD_CREATE_DETACHED 1 #define PTHREAD_CREATE_JOINABLE 0 diff --git a/userspace/libraries/LibC/include/sched.h b/userspace/libraries/LibC/include/sched.h index 05935b6db7..ffbc41f131 100644 --- a/userspace/libraries/LibC/include/sched.h +++ b/userspace/libraries/LibC/include/sched.h @@ -12,14 +12,7 @@ __BEGIN_DECLS #define __need_pid_t #include -struct sched_param -{ - int sched_priority; /* Process or thread execution scheduling priority. */ - int sched_ss_low_priority; /* Low scheduling priority for sporadic server. */ - struct timespec sched_ss_repl_period; /* Replenishment period for sporadic server. */ - struct timespec sched_ss_init_budget; /* Initial budget for sporadic server. */ - int sched_ss_max_repl; /* Maximum pending replenishments for sporadic server. */ -}; +#include #define SCHED_FIFO 1 #define SCHED_RR 2 diff --git a/userspace/libraries/LibC/include/signal.h b/userspace/libraries/LibC/include/signal.h index 47995a184b..7a525d860b 100644 --- a/userspace/libraries/LibC/include/signal.h +++ b/userspace/libraries/LibC/include/signal.h @@ -14,13 +14,14 @@ __BEGIN_DECLS #define SIG_HOLD ((void (*)(int))2) #define SIG_IGN ((void (*)(int))3) -#define __need_pthread_t #define __need_size_t #define __need_uid_t #define __need_pid_t -#define __need_pthread_attr_t #include +#include +#include + typedef int sig_atomic_t; typedef unsigned long long sigset_t; diff --git a/userspace/libraries/LibC/include/sys/types.h b/userspace/libraries/LibC/include/sys/types.h index 89df4b8e91..896ce2067b 100644 --- a/userspace/libraries/LibC/include/sys/types.h +++ b/userspace/libraries/LibC/include/sys/types.h @@ -21,9 +21,6 @@ __BEGIN_DECLS && !defined(__need_nlink_t) \ && !defined(__need_off_t) \ && !defined(__need_pid_t) \ - && !defined(__need_pthread_attr_t) \ - && !defined(__need_pthread_t) \ - && !defined(__need_pthread_types) \ && !defined(__need_size_t) \ && !defined(__need_ssize_t) \ && !defined(__need_suseconds_t) \ @@ -122,18 +119,12 @@ __BEGIN_DECLS #endif #undef __need_off_t -#ifdef __need_pthread_t -#define __need_pid_t -#endif - #if !defined(__pid_t_defined) && (defined(__need_all_types) || defined(__need_pid_t)) #define __pid_t_defined 1 typedef int pid_t; #endif #undef __need_pid_t -#include - #if !defined(__size_t_defined) && (defined(__need_all_types) || defined(__need_size_t)) #define __size_t_defined 1 #define __need_size_t diff --git a/userspace/libraries/LibC/pthread.cpp b/userspace/libraries/LibC/pthread.cpp index 1654166077..cea7510361 100644 --- a/userspace/libraries/LibC/pthread.cpp +++ b/userspace/libraries/LibC/pthread.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -46,13 +47,16 @@ asm( extern "C" void _pthread_trampoline_cpp(void* arg) { auto info = *reinterpret_cast(arg); + info.uthread->id = syscall(SYS_PTHREAD_SELF); + info.uthread->errno_ = 0; + info.uthread->cleanup_stack = nullptr; syscall(SYS_SET_TLS, info.uthread); free(arg); pthread_exit(info.start_routine(info.arg)); ASSERT_NOT_REACHED(); } -static uthread* get_uthread() +uthread* _get_uthread() { uthread* result; #if ARCH(x86_64) @@ -75,22 +79,13 @@ static void free_uthread(uthread* uthread) munmap(tls_addr, tls_size); } -#if not __disable_thread_local_storage -struct pthread_cleanup_t -{ - void (*routine)(void*); - void* arg; - pthread_cleanup_t* next; -}; - -static thread_local pthread_cleanup_t* s_cleanup_stack = nullptr; - void pthread_cleanup_pop(int execute) { - ASSERT(s_cleanup_stack); + uthread* uthread = _get_uthread(); + ASSERT(uthread->cleanup_stack); - auto* cleanup = s_cleanup_stack; - s_cleanup_stack = cleanup->next; + auto* cleanup = uthread->cleanup_stack; + uthread->cleanup_stack = cleanup->next; if (execute) cleanup->routine(cleanup->arg); @@ -100,16 +95,17 @@ void pthread_cleanup_pop(int execute) void pthread_cleanup_push(void (*routine)(void*), void* arg) { - auto* cleanup = static_cast(malloc(sizeof(pthread_cleanup_t))); + auto* cleanup = static_cast<_pthread_cleanup_t*>(malloc(sizeof(_pthread_cleanup_t))); ASSERT(cleanup); + uthread* uthread = _get_uthread(); + cleanup->routine = routine; cleanup->arg = arg; - cleanup->next = s_cleanup_stack; + cleanup->next = uthread->cleanup_stack; - s_cleanup_stack = cleanup; + uthread->cleanup_stack = cleanup; } -#endif #if not __disable_thread_local_storage static thread_local struct { @@ -175,38 +171,156 @@ int pthread_attr_destroy(pthread_attr_t* attr) int pthread_attr_init(pthread_attr_t* attr) { - *attr = 0; - return 0; -} - -int pthread_attr_setstacksize(pthread_attr_t* attr, size_t stacksize) -{ - (void)attr; - (void)stacksize; - dwarnln("TODO: ignoring pthread_attr_setstacksize"); + *attr = { + .inheritsched = PTHREAD_INHERIT_SCHED, + .schedparam = {}, + .schedpolicy = SCHED_RR, + .detachstate = PTHREAD_CREATE_JOINABLE, + .scope = PTHREAD_SCOPE_SYSTEM, + .stacksize = Kernel::Thread::userspace_stack_size, + .guardsize = static_cast(getpagesize()), + }; return 0; } int pthread_attr_getdetachstate(const pthread_attr_t* attr, int* detachstate) { - (void)attr; - *detachstate = PTHREAD_CREATE_JOINABLE; + *detachstate = attr->detachstate; return 0; } int pthread_attr_setdetachstate(pthread_attr_t* attr, int detachstate) { - (void)attr; switch (detachstate) { case PTHREAD_CREATE_DETACHED: dwarnln("TODO: pthread_attr_setdetachstate"); return ENOTSUP; case PTHREAD_CREATE_JOINABLE: + attr->detachstate = detachstate; return 0; - default: - return EINVAL; } + return EINVAL; +} + +int pthread_attr_getguardsize(const pthread_attr_t* __restrict attr, size_t* __restrict guardsize) +{ + *guardsize = attr->guardsize; + return 0; +} + +int pthread_attr_setguardsize(pthread_attr_t* attr, size_t guardsize) +{ + attr->guardsize = guardsize; + return 0; +} + +int pthread_attr_getinheritsched(const pthread_attr_t* __restrict attr, int* __restrict inheritsched) +{ + *inheritsched = attr->inheritsched; + return 0; +} + +int pthread_attr_setinheritsched(pthread_attr_t* attr, int inheritsched) +{ + switch (inheritsched) + { + case PTHREAD_INHERIT_SCHED: + case PTHREAD_EXPLICIT_SCHED: + attr->inheritsched = inheritsched; + return 0; + } + return EINVAL; +} + +int pthread_attr_getschedparam(const pthread_attr_t* __restrict attr, struct sched_param* __restrict param) +{ + *param = attr->schedparam; + return 0; +} + +int pthread_attr_setschedparam(pthread_attr_t* __restrict attr, const struct sched_param* __restrict param) +{ + attr->schedparam = *param; + return 0; +} + +int pthread_attr_getschedpolicy(const pthread_attr_t* __restrict attr, int* __restrict policy) +{ + *policy = attr->schedpolicy; + return 0; +} + +int pthread_attr_setschedpolicy(pthread_attr_t* attr, int policy) +{ + switch (policy) + { + case SCHED_FIFO: + case SCHED_SPORADIC: + case SCHED_OTHER: + return ENOTSUP; + case SCHED_RR: + attr->schedpolicy = policy; + return 0; + } + return EINVAL; +} + +int pthread_attr_getscope(const pthread_attr_t* __restrict attr, int* __restrict contentionscope) +{ + *contentionscope = attr->scope; + return 0; +} + +int pthread_attr_setscope(pthread_attr_t* attr, int contentionscope) +{ + switch (contentionscope) + { + case PTHREAD_SCOPE_PROCESS: + return ENOTSUP; + case PTHREAD_SCOPE_SYSTEM: + attr->scope = contentionscope; + return 0; + } + return EINVAL; +} + +int pthread_attr_getstack(const pthread_attr_t* __restrict attr, void** __restrict stackaddr, size_t* __restrict stacksize) +{ + (void)attr; + (void)stackaddr; + (void)stacksize; + dwarnln("TODO: pthread_attr_getstack"); + return ENOTSUP; +} + +int pthread_attr_setstack(pthread_attr_t* attr, void* stackaddr, size_t stacksize) +{ + (void)attr; + (void)stackaddr; + (void)stacksize; + dwarnln("TODO: pthread_attr_setstack"); + return ENOTSUP; +} + +int pthread_attr_getstacksize(const pthread_attr_t* __restrict attr, size_t* __restrict stacksize) +{ + *stacksize = attr->stacksize; + return 0; +} + +int pthread_attr_setstacksize(pthread_attr_t* attr, size_t stacksize) +{ + attr->stacksize = stacksize; + return 0; +} + +int pthread_setcancelstate(int state, int* oldstate) +{ + (void)state; + (void)oldstate; + dwarnln("TODO: pthread_setcancelstate"); + return 0; } int pthread_create(pthread_t* __restrict thread_id, const pthread_attr_t* __restrict attr, void* (*start_routine)(void*), void* __restrict arg) @@ -223,14 +337,20 @@ int pthread_create(pthread_t* __restrict thread_id, const pthread_attr_t* __rest long syscall_ret = 0; - if (uthread* self = get_uthread(); self->master_tls_addr == nullptr) + if (uthread* self = _get_uthread(); self->master_tls_addr == nullptr) { uthread* uthread = static_cast(malloc(sizeof(struct uthread) + sizeof(uintptr_t))); if (uthread == nullptr) goto pthread_create_error; - uthread->self = uthread; - uthread->master_tls_addr = nullptr; - uthread->master_tls_size = 0; + + *uthread = { + .self = uthread, + .master_tls_addr = nullptr, + .master_tls_size = 0, + .cleanup_stack = nullptr, + .id = -1, + .errno_ = 0, + }; uthread->dtv[0] = 0; info->uthread = uthread; @@ -249,9 +369,14 @@ int pthread_create(pthread_t* __restrict thread_id, const pthread_attr_t* __rest memcpy(tls_addr, self->master_tls_addr, self->master_tls_size); uthread* uthread = reinterpret_cast(tls_addr + self->master_tls_size); - uthread->self = uthread; - uthread->master_tls_addr = self->master_tls_addr; - uthread->master_tls_size = self->master_tls_size; + *uthread = { + .self = uthread, + .master_tls_addr = self->master_tls_addr, + .master_tls_size = self->master_tls_size, + .cleanup_stack = nullptr, + .id = -1, + .errno_ = 0, + }; const uintptr_t self_addr = reinterpret_cast(self); const uintptr_t uthread_addr = reinterpret_cast(uthread); @@ -288,9 +413,11 @@ int pthread_detach(pthread_t thread) void pthread_exit(void* value_ptr) { -#if not __disable_thread_local_storage - while (s_cleanup_stack) + uthread* uthread = _get_uthread(); + while (uthread->cleanup_stack) pthread_cleanup_pop(1); + +#if not __disable_thread_local_storage for (size_t iteration = 0; iteration < PTHREAD_DESTRUCTOR_ITERATIONS; iteration++) { bool called = false; @@ -309,7 +436,8 @@ void pthread_exit(void* value_ptr) break; } #endif - free_uthread(get_uthread()); + + free_uthread(uthread); syscall(SYS_PTHREAD_EXIT, value_ptr); ASSERT_NOT_REACHED(); } @@ -326,14 +454,7 @@ int pthread_join(pthread_t thread, void** value_ptr) pthread_t pthread_self(void) { -#if __disable_thread_local_storage - return syscall(SYS_PTHREAD_SELF); -#else - static thread_local pthread_t s_pthread_self { -1 }; - if (s_pthread_self == -1) [[unlikely]] - s_pthread_self = syscall(SYS_PTHREAD_SELF); - return s_pthread_self; -#endif + return _get_uthread()->id; } int pthread_once(pthread_once_t* once_control, void (*init_routine)(void)) @@ -732,7 +853,7 @@ int pthread_condattr_getpshared(const pthread_condattr_t* __restrict attr, int* return 0; } -int pthread_condattr_setpshared(pthread_barrierattr_t* attr, int pshared) +int pthread_condattr_setpshared(pthread_condattr_t* attr, int pshared) { switch (pshared) { @@ -925,7 +1046,7 @@ struct tls_index extern "C" void* __tls_get_addr(tls_index* ti) { - return reinterpret_cast(get_uthread()->dtv[ti->ti_module] + ti->ti_offset); + return reinterpret_cast(_get_uthread()->dtv[ti->ti_module] + ti->ti_offset); } #if ARCH(i686) diff --git a/userspace/libraries/LibC/unistd.cpp b/userspace/libraries/LibC/unistd.cpp index 4b98113cc0..b9f79113f6 100644 --- a/userspace/libraries/LibC/unistd.cpp +++ b/userspace/libraries/LibC/unistd.cpp @@ -34,7 +34,13 @@ extern "C" void _init_libc(char** environ, init_funcs_t init_funcs, init_funcs_t if (::environ == nullptr) ::environ = environ; - if (syscall(SYS_GET_TLS) == 0) + if (uthread* self = reinterpret_cast(syscall(SYS_GET_TLS))) + { + self->cleanup_stack = nullptr; + self->id = syscall(SYS_PTHREAD_SELF); + self->errno_ = 0; + } + else { alignas(uthread) static uint8_t storage[sizeof(uthread) + sizeof(uintptr_t)]; @@ -43,6 +49,9 @@ extern "C" void _init_libc(char** environ, init_funcs_t init_funcs, init_funcs_t .self = &uthread, .master_tls_addr = nullptr, .master_tls_size = 0, + .cleanup_stack = nullptr, + .id = static_cast(syscall(SYS_PTHREAD_SELF)), + .errno_ = 0, }; uthread.dtv[0] = 0;