diff options
Diffstat (limited to 'src/thread')
| -rw-r--r-- | src/thread/pthread_attr_getinheritsched.c | 7 | ||||
| -rw-r--r-- | src/thread/pthread_attr_getschedparam.c | 2 | ||||
| -rw-r--r-- | src/thread/pthread_attr_getschedpolicy.c | 7 | ||||
| -rw-r--r-- | src/thread/pthread_attr_getscope.c | 1 | ||||
| -rw-r--r-- | src/thread/pthread_attr_setinheritsched.c | 8 | ||||
| -rw-r--r-- | src/thread/pthread_attr_setschedparam.c | 2 | ||||
| -rw-r--r-- | src/thread/pthread_attr_setschedpolicy.c | 7 | ||||
| -rw-r--r-- | src/thread/pthread_attr_setscope.c | 10 | ||||
| -rw-r--r-- | src/thread/pthread_create.c | 29 | ||||
| -rw-r--r-- | src/thread/pthread_getschedparam.c | 17 | ||||
| -rw-r--r-- | src/thread/pthread_setschedparam.c | 10 | ||||
| -rw-r--r-- | src/thread/pthread_setschedprio.c | 10 | 
12 files changed, 106 insertions, 4 deletions
| diff --git a/src/thread/pthread_attr_getinheritsched.c b/src/thread/pthread_attr_getinheritsched.c new file mode 100644 index 00000000..392a5df8 --- /dev/null +++ b/src/thread/pthread_attr_getinheritsched.c @@ -0,0 +1,7 @@ +#include "pthread_impl.h" + +int pthread_attr_getinheritsched(const pthread_attr_t *a, int *inherit) +{ +	*inherit = a->_a_sched; +	return 0; +} diff --git a/src/thread/pthread_attr_getschedparam.c b/src/thread/pthread_attr_getschedparam.c index 5806bdf1..de5fbfe2 100644 --- a/src/thread/pthread_attr_getschedparam.c +++ b/src/thread/pthread_attr_getschedparam.c @@ -2,6 +2,6 @@  int pthread_attr_getschedparam(const pthread_attr_t *restrict a, struct sched_param *restrict param)  { -	param->sched_priority = 0; +	param->sched_priority = a->_a_prio;  	return 0;  } diff --git a/src/thread/pthread_attr_getschedpolicy.c b/src/thread/pthread_attr_getschedpolicy.c new file mode 100644 index 00000000..09e893a3 --- /dev/null +++ b/src/thread/pthread_attr_getschedpolicy.c @@ -0,0 +1,7 @@ +#include "pthread_impl.h" + +int pthread_attr_getschedpolicy(const pthread_attr_t *a, int *policy) +{ +	*policy = a->_a_policy; +	return 0; +} diff --git a/src/thread/pthread_attr_getscope.c b/src/thread/pthread_attr_getscope.c index c0167b6a..b8dfd123 100644 --- a/src/thread/pthread_attr_getscope.c +++ b/src/thread/pthread_attr_getscope.c @@ -2,5 +2,6 @@  int pthread_attr_getscope(const pthread_attr_t *restrict a, int *restrict scope)  { +	*scope = PTHREAD_SCOPE_SYSTEM;  	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_create.c b/src/thread/pthread_create.c index a7aadb51..a65e88e1 100644 --- a/src/thread/pthread_create.c +++ b/src/thread/pthread_create.c @@ -62,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); @@ -95,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) { @@ -144,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; @@ -152,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_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; +} | 
