diff options
Diffstat (limited to 'src/thread')
33 files changed, 196 insertions, 104 deletions
diff --git a/src/thread/__wake.c b/src/thread/__wake.c index 8fd0599c..d8bf70f7 100644 --- a/src/thread/__wake.c +++ b/src/thread/__wake.c @@ -1,4 +1,5 @@ #include "pthread_impl.h" +#include <limits.h> void __wake(volatile int *addr, int cnt, int priv) { diff --git a/src/thread/pthread_attr_get.c b/src/thread/pthread_attr_get.c new file mode 100644 index 00000000..f81103d8 --- /dev/null +++ b/src/thread/pthread_attr_get.c @@ -0,0 +1,93 @@ +#include "pthread_impl.h" + +int pthread_attr_getdetachstate(const pthread_attr_t *a, int *state) +{ + *state = a->_a_detach; + return 0; +} +int pthread_attr_getguardsize(const pthread_attr_t *restrict a, size_t *restrict size) +{ + *size = a->_a_guardsize + DEFAULT_GUARD_SIZE; + return 0; +} + +int pthread_attr_getinheritsched(const pthread_attr_t *a, int *inherit) +{ + *inherit = a->_a_sched; + return 0; +} + +int pthread_attr_getschedparam(const pthread_attr_t *restrict a, struct sched_param *restrict param) +{ + param->sched_priority = a->_a_prio; + return 0; +} + +int pthread_attr_getschedpolicy(const pthread_attr_t *a, int *policy) +{ + *policy = a->_a_policy; + return 0; +} + +int pthread_attr_getscope(const pthread_attr_t *restrict a, int *restrict scope) +{ + *scope = PTHREAD_SCOPE_SYSTEM; + return 0; +} + +int pthread_attr_getstack(const pthread_attr_t *restrict a, void **restrict addr, size_t *restrict size) +{ + if (!a->_a_stackaddr) + return EINVAL; + *size = a->_a_stacksize + DEFAULT_STACK_SIZE; + *addr = (void *)(a->_a_stackaddr - *size); + return 0; +} + +int pthread_attr_getstacksize(const pthread_attr_t *restrict a, size_t *restrict size) +{ + *size = a->_a_stacksize + DEFAULT_STACK_SIZE; + return 0; +} + +int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict a, int *restrict pshared) +{ + *pshared = !!*a; + return 0; +} + +int pthread_condattr_getclock(const pthread_condattr_t *restrict a, clockid_t *restrict clk) +{ + *clk = *a & 0x7fffffff; + return 0; +} + +int pthread_condattr_getpshared(const pthread_condattr_t *restrict a, int *restrict pshared) +{ + *pshared = *a>>31; + return 0; +} + +int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict a, int *restrict pshared) +{ + *pshared = *a>>31; + return 0; +} + +int pthread_mutexattr_getrobust(const pthread_mutexattr_t *restrict a, int *restrict robust) +{ + *robust = *a / 4U % 2; + return 0; +} + +int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict a, int *restrict type) +{ + *type = *a & 3; + return 0; +} + +int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict a, int *restrict pshared) +{ + *pshared = *(int *)a; + return 0; +} diff --git a/src/thread/pthread_attr_getdetachstate.c b/src/thread/pthread_attr_getdetachstate.c deleted file mode 100644 index 47c4c023..00000000 --- a/src/thread/pthread_attr_getdetachstate.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "pthread_impl.h" - -int pthread_attr_getdetachstate(const pthread_attr_t *a, int *state) -{ - *state = a->_a_detach; - return 0; -} diff --git a/src/thread/pthread_attr_getguardsize.c b/src/thread/pthread_attr_getguardsize.c deleted file mode 100644 index 93ba05dd..00000000 --- a/src/thread/pthread_attr_getguardsize.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "pthread_impl.h" - -int pthread_attr_getguardsize(const pthread_attr_t *restrict a, size_t *restrict size) -{ - *size = a->_a_guardsize + DEFAULT_GUARD_SIZE; - return 0; -} diff --git a/src/thread/pthread_attr_getschedparam.c b/src/thread/pthread_attr_getschedparam.c deleted file mode 100644 index 5806bdf1..00000000 --- a/src/thread/pthread_attr_getschedparam.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "pthread_impl.h" - -int pthread_attr_getschedparam(const pthread_attr_t *restrict a, struct sched_param *restrict param) -{ - param->sched_priority = 0; - return 0; -} diff --git a/src/thread/pthread_attr_getscope.c b/src/thread/pthread_attr_getscope.c deleted file mode 100644 index c0167b6a..00000000 --- a/src/thread/pthread_attr_getscope.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "pthread_impl.h" - -int pthread_attr_getscope(const pthread_attr_t *restrict a, int *restrict scope) -{ - return 0; -} diff --git a/src/thread/pthread_attr_getstack.c b/src/thread/pthread_attr_getstack.c deleted file mode 100644 index 70adbb03..00000000 --- a/src/thread/pthread_attr_getstack.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "pthread_impl.h" - -int pthread_attr_getstack(const pthread_attr_t *restrict a, void **restrict addr, size_t *restrict size) -{ - if (!a->_a_stackaddr) - return EINVAL; - *size = a->_a_stacksize + DEFAULT_STACK_SIZE; - *addr = (void *)(a->_a_stackaddr - *size); - return 0; -} diff --git a/src/thread/pthread_attr_getstacksize.c b/src/thread/pthread_attr_getstacksize.c deleted file mode 100644 index f69cc1e6..00000000 --- a/src/thread/pthread_attr_getstacksize.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "pthread_impl.h" - -int pthread_attr_getstacksize(const pthread_attr_t *restrict a, size_t *restrict size) -{ - *size = a->_a_stacksize + DEFAULT_STACK_SIZE; - return 0; -} diff --git a/src/thread/pthread_attr_init.c b/src/thread/pthread_attr_init.c index d91bf157..66934889 100644 --- a/src/thread/pthread_attr_init.c +++ b/src/thread/pthread_attr_init.c @@ -1,7 +1,8 @@ #include "pthread_impl.h" +#include <string.h> int pthread_attr_init(pthread_attr_t *a) { - memset(a, 0, sizeof *a); + *a = (pthread_attr_t){0}; return 0; } diff --git a/src/thread/pthread_attr_setinheritsched.c b/src/thread/pthread_attr_setinheritsched.c new file mode 100644 index 00000000..c91d8f83 --- /dev/null +++ b/src/thread/pthread_attr_setinheritsched.c @@ -0,0 +1,8 @@ +#include "pthread_impl.h" + +int pthread_attr_setinheritsched(pthread_attr_t *a, int inherit) +{ + if (inherit > 1U) return EINVAL; + a->_a_sched = inherit; + return 0; +} diff --git a/src/thread/pthread_attr_setschedparam.c b/src/thread/pthread_attr_setschedparam.c index 77ce9c98..d4c1204f 100644 --- a/src/thread/pthread_attr_setschedparam.c +++ b/src/thread/pthread_attr_setschedparam.c @@ -2,6 +2,6 @@ int pthread_attr_setschedparam(pthread_attr_t *restrict a, const struct sched_param *restrict param) { - if (param->sched_priority) return ENOTSUP; + a->_a_prio = param->sched_priority; return 0; } diff --git a/src/thread/pthread_attr_setschedpolicy.c b/src/thread/pthread_attr_setschedpolicy.c new file mode 100644 index 00000000..bb71f393 --- /dev/null +++ b/src/thread/pthread_attr_setschedpolicy.c @@ -0,0 +1,7 @@ +#include "pthread_impl.h" + +int pthread_attr_setschedpolicy(pthread_attr_t *a, int policy) +{ + a->_a_policy = policy; + return 0; +} diff --git a/src/thread/pthread_attr_setscope.c b/src/thread/pthread_attr_setscope.c index d56ee391..46b520c0 100644 --- a/src/thread/pthread_attr_setscope.c +++ b/src/thread/pthread_attr_setscope.c @@ -2,6 +2,12 @@ int pthread_attr_setscope(pthread_attr_t *a, int scope) { - if (scope > 1U) return EINVAL; - return 0; + switch (scope) { + case PTHREAD_SCOPE_SYSTEM: + return 0; + case PTHREAD_SCOPE_PROCESS: + return ENOTSUP; + default: + return EINVAL; + } } diff --git a/src/thread/pthread_barrierattr_getpshared.c b/src/thread/pthread_barrierattr_getpshared.c deleted file mode 100644 index df337c29..00000000 --- a/src/thread/pthread_barrierattr_getpshared.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "pthread_impl.h" - -int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict a, int *restrict pshared) -{ - *pshared = !!*a; - return 0; -} diff --git a/src/thread/pthread_barrierattr_init.c b/src/thread/pthread_barrierattr_init.c index f2698272..fa742bb7 100644 --- a/src/thread/pthread_barrierattr_init.c +++ b/src/thread/pthread_barrierattr_init.c @@ -2,6 +2,6 @@ int pthread_barrierattr_init(pthread_barrierattr_t *a) { - memset(a, 0, sizeof *a); + *a = (pthread_barrierattr_t){0}; return 0; } diff --git a/src/thread/pthread_cond_init.c b/src/thread/pthread_cond_init.c index 2eac30f1..71489bca 100644 --- a/src/thread/pthread_cond_init.c +++ b/src/thread/pthread_cond_init.c @@ -2,7 +2,7 @@ int pthread_cond_init(pthread_cond_t *restrict c, const pthread_condattr_t *restrict a) { - memset(c, 0, sizeof *c); + *c = (pthread_cond_t){0}; if (a) { c->_c_clock = *a & 0x7fffffff; if (*a>>31) c->_c_mutex = (void *)-1; diff --git a/src/thread/pthread_condattr_getclock.c b/src/thread/pthread_condattr_getclock.c deleted file mode 100644 index d2933843..00000000 --- a/src/thread/pthread_condattr_getclock.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "pthread_impl.h" - -int pthread_condattr_getclock(const pthread_condattr_t *restrict a, clockid_t *restrict clk) -{ - *clk = *a & 0x7fffffff; - return 0; -} diff --git a/src/thread/pthread_condattr_getpshared.c b/src/thread/pthread_condattr_getpshared.c deleted file mode 100644 index 4991e495..00000000 --- a/src/thread/pthread_condattr_getpshared.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "pthread_impl.h" - -int pthread_condattr_getpshared(const pthread_condattr_t *restrict a, int *restrict pshared) -{ - *pshared = *a>>31; - return 0; -} diff --git a/src/thread/pthread_condattr_init.c b/src/thread/pthread_condattr_init.c index 6d09ac1e..a41741b4 100644 --- a/src/thread/pthread_condattr_init.c +++ b/src/thread/pthread_condattr_init.c @@ -2,6 +2,6 @@ int pthread_condattr_init(pthread_condattr_t *a) { - memset(a, 0, sizeof *a); + *a = (pthread_condattr_t){0}; return 0; } diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c index e67616e7..a65e88e1 100644 --- a/src/thread/pthread_create.c +++ b/src/thread/pthread_create.c @@ -1,5 +1,6 @@ #include "pthread_impl.h" #include "stdio_impl.h" +#include <sys/mman.h> static void dummy_0() { @@ -61,6 +62,15 @@ void __do_cleanup_pop(struct __ptcb *cb) static int start(void *p) { pthread_t self = p; + if (self->startlock[0]) { + __wait(self->startlock, 0, 1, 1); + if (self->startlock[0]) { + self->detached = 2; + pthread_exit(0); + } + __syscall(SYS_rt_sigprocmask, SIG_SETMASK, + self->sigmask, 0, __SYSCALL_SSLEN); + } if (self->unblock_cancel) __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, SIGPT_SET, 0, __SYSCALL_SSLEN); @@ -94,6 +104,7 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attr, struct pthread *self = pthread_self(), *new; unsigned char *map, *stack, *tsd; unsigned flags = 0x7d8f00; + int do_sched = 0; if (!self) return ENOSYS; if (!libc.threaded) { @@ -143,6 +154,11 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attr, new->detached = 1; flags -= 0x200000; } + if (attr && attr->_a_sched) { + do_sched = new->startlock[0] = 1; + __syscall(SYS_rt_sigprocmask, SIG_BLOCK, + SIGALL_SET, self->sigmask, __SYSCALL_SSLEN); + } new->unblock_cancel = self->cancel; new->canary = self->canary; @@ -151,11 +167,25 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attr, __release_ptc(); + if (do_sched) { + __syscall(SYS_rt_sigprocmask, SIG_SETMASK, + new->sigmask, 0, __SYSCALL_SSLEN); + } + if (ret < 0) { a_dec(&libc.threads_minus_1); munmap(map, size); return EAGAIN; } + + if (do_sched) { + ret = __syscall(SYS_sched_setscheduler, new->tid, + attr->_a_policy, &attr->_a_prio); + a_store(new->startlock, ret<0 ? 2 : 0); + __wake(new->startlock, 1, 1); + if (ret < 0) return -ret; + } + *res = new; return 0; } diff --git a/src/thread/pthread_getschedparam.c b/src/thread/pthread_getschedparam.c new file mode 100644 index 00000000..7b6a95f1 --- /dev/null +++ b/src/thread/pthread_getschedparam.c @@ -0,0 +1,17 @@ +#include "pthread_impl.h" + +int pthread_getschedparam(pthread_t t, int *restrict policy, struct sched_param *restrict param) +{ + int r; + __lock(t->killlock); + if (t->dead) { + r = ESRCH; + } else { + r = -__syscall(SYS_sched_getparam, t->tid, ¶m); + if (!r) { + *policy = __syscall(SYS_sched_getscheduler, t->tid); + } + } + __unlock(t->killlock); + return r; +} diff --git a/src/thread/pthread_join.c b/src/thread/pthread_join.c index 86191f25..719c91ca 100644 --- a/src/thread/pthread_join.c +++ b/src/thread/pthread_join.c @@ -1,4 +1,5 @@ #include "pthread_impl.h" +#include <sys/mman.h> static void dummy(void *p) { diff --git a/src/thread/pthread_mutex_init.c b/src/thread/pthread_mutex_init.c index fb689271..a7ba39ba 100644 --- a/src/thread/pthread_mutex_init.c +++ b/src/thread/pthread_mutex_init.c @@ -2,7 +2,7 @@ int pthread_mutex_init(pthread_mutex_t *restrict m, const pthread_mutexattr_t *restrict a) { - memset(m, 0, sizeof *m); + *m = (pthread_mutex_t){0}; if (a) m->_m_type = *a & 7; return 0; } diff --git a/src/thread/pthread_mutexattr_getpshared.c b/src/thread/pthread_mutexattr_getpshared.c deleted file mode 100644 index e7340b1a..00000000 --- a/src/thread/pthread_mutexattr_getpshared.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "pthread_impl.h" - -int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict a, int *restrict pshared) -{ - *pshared = *a>>31; - return 0; -} diff --git a/src/thread/pthread_mutexattr_getrobust.c b/src/thread/pthread_mutexattr_getrobust.c deleted file mode 100644 index 4d176f20..00000000 --- a/src/thread/pthread_mutexattr_getrobust.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "pthread_impl.h" - -int pthread_mutexattr_getrobust(const pthread_mutexattr_t *restrict a, int *restrict robust) -{ - *robust = *a / 4U % 2; - return 0; -} diff --git a/src/thread/pthread_mutexattr_gettype.c b/src/thread/pthread_mutexattr_gettype.c deleted file mode 100644 index 7688b068..00000000 --- a/src/thread/pthread_mutexattr_gettype.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "pthread_impl.h" - -int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict a, int *restrict type) -{ - *type = *a & 3; - return 0; -} diff --git a/src/thread/pthread_mutexattr_init.c b/src/thread/pthread_mutexattr_init.c index ea631069..0b72c1ba 100644 --- a/src/thread/pthread_mutexattr_init.c +++ b/src/thread/pthread_mutexattr_init.c @@ -2,6 +2,6 @@ int pthread_mutexattr_init(pthread_mutexattr_t *a) { - memset(a, 0, sizeof *a); + *a = (pthread_mutexattr_t){0}; return 0; } diff --git a/src/thread/pthread_rwlock_init.c b/src/thread/pthread_rwlock_init.c index 29003bc6..82df52e2 100644 --- a/src/thread/pthread_rwlock_init.c +++ b/src/thread/pthread_rwlock_init.c @@ -2,7 +2,7 @@ int pthread_rwlock_init(pthread_rwlock_t *restrict rw, const pthread_rwlockattr_t *restrict a) { - memset(rw, 0, sizeof *rw); + *rw = (pthread_rwlock_t){0}; if (a) { } return 0; diff --git a/src/thread/pthread_rwlockattr_getpshared.c b/src/thread/pthread_rwlockattr_getpshared.c deleted file mode 100644 index 02fd8c80..00000000 --- a/src/thread/pthread_rwlockattr_getpshared.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "pthread_impl.h" - -int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict a, int *restrict pshared) -{ - *pshared = *(int *)a; - return 0; -} diff --git a/src/thread/pthread_rwlockattr_init.c b/src/thread/pthread_rwlockattr_init.c index e0893d67..e7420694 100644 --- a/src/thread/pthread_rwlockattr_init.c +++ b/src/thread/pthread_rwlockattr_init.c @@ -2,6 +2,6 @@ int pthread_rwlockattr_init(pthread_rwlockattr_t *a) { - memset(a, 0, sizeof *a); + *a = (pthread_rwlockattr_t){0}; return 0; } diff --git a/src/thread/pthread_setschedparam.c b/src/thread/pthread_setschedparam.c new file mode 100644 index 00000000..8e8b5a19 --- /dev/null +++ b/src/thread/pthread_setschedparam.c @@ -0,0 +1,10 @@ +#include "pthread_impl.h" + +int pthread_setschedparam(pthread_t t, int policy, const struct sched_param *param) +{ + int r; + __lock(t->killlock); + r = t->dead ? ESRCH : -__syscall(SYS_sched_setscheduler, t->tid, policy, ¶m); + __unlock(t->killlock); + return r; +} diff --git a/src/thread/pthread_setschedprio.c b/src/thread/pthread_setschedprio.c new file mode 100644 index 00000000..e0bdc03b --- /dev/null +++ b/src/thread/pthread_setschedprio.c @@ -0,0 +1,10 @@ +#include "pthread_impl.h" + +int pthread_setschedprio(pthread_t t, int prio) +{ + int r; + __lock(t->killlock); + r = t->dead ? ESRCH : -__syscall(SYS_sched_setparam, t->tid, &prio); + __unlock(t->killlock); + return r; +} diff --git a/src/thread/synccall.c b/src/thread/synccall.c index 2b7eac25..dc59863f 100644 --- a/src/thread/synccall.c +++ b/src/thread/synccall.c @@ -1,5 +1,6 @@ #include "pthread_impl.h" #include <semaphore.h> +#include <string.h> static struct chain { struct chain *next; |