about summary refs log tree commit diff
path: root/src/thread
diff options
context:
space:
mode:
Diffstat (limited to 'src/thread')
-rw-r--r--src/thread/__wake.c1
-rw-r--r--src/thread/pthread_attr_get.c93
-rw-r--r--src/thread/pthread_attr_getdetachstate.c7
-rw-r--r--src/thread/pthread_attr_getguardsize.c7
-rw-r--r--src/thread/pthread_attr_getschedparam.c7
-rw-r--r--src/thread/pthread_attr_getscope.c6
-rw-r--r--src/thread/pthread_attr_getstack.c10
-rw-r--r--src/thread/pthread_attr_getstacksize.c7
-rw-r--r--src/thread/pthread_attr_init.c3
-rw-r--r--src/thread/pthread_attr_setinheritsched.c8
-rw-r--r--src/thread/pthread_attr_setschedparam.c2
-rw-r--r--src/thread/pthread_attr_setschedpolicy.c7
-rw-r--r--src/thread/pthread_attr_setscope.c10
-rw-r--r--src/thread/pthread_barrierattr_getpshared.c7
-rw-r--r--src/thread/pthread_barrierattr_init.c2
-rw-r--r--src/thread/pthread_cond_init.c2
-rw-r--r--src/thread/pthread_condattr_getclock.c7
-rw-r--r--src/thread/pthread_condattr_getpshared.c7
-rw-r--r--src/thread/pthread_condattr_init.c2
-rw-r--r--src/thread/pthread_create.c30
-rw-r--r--src/thread/pthread_getschedparam.c17
-rw-r--r--src/thread/pthread_join.c1
-rw-r--r--src/thread/pthread_mutex_init.c2
-rw-r--r--src/thread/pthread_mutexattr_getpshared.c7
-rw-r--r--src/thread/pthread_mutexattr_getrobust.c7
-rw-r--r--src/thread/pthread_mutexattr_gettype.c7
-rw-r--r--src/thread/pthread_mutexattr_init.c2
-rw-r--r--src/thread/pthread_rwlock_init.c2
-rw-r--r--src/thread/pthread_rwlockattr_getpshared.c7
-rw-r--r--src/thread/pthread_rwlockattr_init.c2
-rw-r--r--src/thread/pthread_setschedparam.c10
-rw-r--r--src/thread/pthread_setschedprio.c10
-rw-r--r--src/thread/synccall.c1
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, &param);
+		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, &param);
+	__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;