xref: /netbsd/lib/libpthread/pthread_misc.c (revision 6d153667)
1*6d153667Sad /*	$NetBSD: pthread_misc.c,v 1.9 2008/06/24 13:45:07 ad Exp $	*/
2de213816Sad 
3de213816Sad /*-
45c71a4d4Srmind  * Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
5de213816Sad  * All rights reserved.
6de213816Sad  *
7de213816Sad  * This code is derived from software contributed to The NetBSD Foundation
8de213816Sad  * by Nathan J. Williams.
9de213816Sad  *
10de213816Sad  * Redistribution and use in source and binary forms, with or without
11de213816Sad  * modification, are permitted provided that the following conditions
12de213816Sad  * are met:
13de213816Sad  * 1. Redistributions of source code must retain the above copyright
14de213816Sad  *    notice, this list of conditions and the following disclaimer.
15de213816Sad  * 2. Redistributions in binary form must reproduce the above copyright
16de213816Sad  *    notice, this list of conditions and the following disclaimer in the
17de213816Sad  *    documentation and/or other materials provided with the distribution.
18de213816Sad  *
19de213816Sad  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20de213816Sad  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21de213816Sad  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22de213816Sad  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23de213816Sad  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24de213816Sad  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25de213816Sad  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26de213816Sad  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27de213816Sad  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28de213816Sad  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29de213816Sad  * POSSIBILITY OF SUCH DAMAGE.
30de213816Sad  */
31de213816Sad 
32de213816Sad #include <sys/cdefs.h>
33*6d153667Sad __RCSID("$NetBSD: pthread_misc.c,v 1.9 2008/06/24 13:45:07 ad Exp $");
345c71a4d4Srmind 
355c71a4d4Srmind #include <errno.h>
365c71a4d4Srmind #include <string.h>
375c71a4d4Srmind #include <unistd.h>
38de213816Sad 
39de213816Sad #include <sys/types.h>
405c71a4d4Srmind #include <sys/pset.h>
41de213816Sad #include <sys/signal.h>
42de213816Sad #include <sys/time.h>
43de213816Sad 
44de213816Sad #include <lwp.h>
455c71a4d4Srmind #include <sched.h>
46de213816Sad 
47de213816Sad #include "pthread.h"
48de213816Sad #include "pthread_int.h"
49de213816Sad 
5066ac2ffaSad int	pthread__sched_yield(void);
5166ac2ffaSad 
52de213816Sad int	_sys___sigprocmask14(int, const sigset_t *, sigset_t *);
53de213816Sad int	_sys_nanosleep(const struct timespec *, struct timespec *);
5466ac2ffaSad int	_sys_sched_yield(void);
55de213816Sad 
56de213816Sad __strong_alias(_nanosleep, nanosleep)
57de213816Sad __strong_alias(__libc_thr_sigsetmask,pthread_sigmask)
58de213816Sad __strong_alias(__sigprocmask14,pthread_sigmask)
5966ac2ffaSad __strong_alias(__libc_thr_yield,pthread__sched_yield)
60de213816Sad 
61de213816Sad int
62de213816Sad pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param)
63de213816Sad {
645c71a4d4Srmind 
655c71a4d4Srmind 	if (pthread__find(thread) != 0)
665c71a4d4Srmind 		return ESRCH;
675c71a4d4Srmind 
68603e4b9aSyamt 	if (_sched_getparam(getpid(), thread->pt_lid, policy, param) < 0)
69b5e9adddSrmind 		return errno;
70b5e9adddSrmind 
71b5e9adddSrmind 	return 0;
72de213816Sad }
73de213816Sad 
74de213816Sad int
75de213816Sad pthread_setschedparam(pthread_t thread, int policy,
76de213816Sad     const struct sched_param *param)
77de213816Sad {
785c71a4d4Srmind 	struct sched_param sp;
795c71a4d4Srmind 
805c71a4d4Srmind 	if (pthread__find(thread) != 0)
815c71a4d4Srmind 		return ESRCH;
825c71a4d4Srmind 
835c71a4d4Srmind 	memcpy(&sp, param, sizeof(struct sched_param));
84603e4b9aSyamt 	if (_sched_setparam(getpid(), thread->pt_lid, policy, &sp) < 0)
85b5e9adddSrmind 		return errno;
86b5e9adddSrmind 
87b5e9adddSrmind 	return 0;
885c71a4d4Srmind }
895c71a4d4Srmind 
905c71a4d4Srmind int
915c71a4d4Srmind pthread_getaffinity_np(pthread_t thread, size_t size, cpuset_t *cpuset)
925c71a4d4Srmind {
935c71a4d4Srmind 
945c71a4d4Srmind 	if (pthread__find(thread) != 0)
955c71a4d4Srmind 		return ESRCH;
965c71a4d4Srmind 
97b5e9adddSrmind 	if (_sched_getaffinity(getpid(), thread->pt_lid, size, cpuset) < 0)
98b5e9adddSrmind 		return errno;
99b5e9adddSrmind 
100b5e9adddSrmind 	return 0;
1015c71a4d4Srmind }
1025c71a4d4Srmind 
1035c71a4d4Srmind int
1045c71a4d4Srmind pthread_setaffinity_np(pthread_t thread, size_t size, cpuset_t *cpuset)
1055c71a4d4Srmind {
1065c71a4d4Srmind 
1075c71a4d4Srmind 	if (pthread__find(thread) != 0)
1085c71a4d4Srmind 		return ESRCH;
1095c71a4d4Srmind 
110b5e9adddSrmind 	if (_sched_setaffinity(getpid(), thread->pt_lid, size, cpuset) < 0)
111b5e9adddSrmind 		return errno;
112b5e9adddSrmind 
113b5e9adddSrmind 	return 0;
1145c71a4d4Srmind }
1155c71a4d4Srmind 
1165c71a4d4Srmind int
1175c71a4d4Srmind pthread_setschedprio(pthread_t thread, int prio)
1185c71a4d4Srmind {
1195c71a4d4Srmind 	struct sched_param sp;
1205c71a4d4Srmind 
1215c71a4d4Srmind 	if (pthread__find(thread) != 0)
1225c71a4d4Srmind 		return ESRCH;
1235c71a4d4Srmind 
1245c71a4d4Srmind 	sp.sched_priority = prio;
125603e4b9aSyamt 	if (_sched_setparam(getpid(), thread->pt_lid, SCHED_NONE, &sp) < 0)
126b5e9adddSrmind 		return errno;
127b5e9adddSrmind 
128b5e9adddSrmind 	return 0;
129de213816Sad }
130de213816Sad 
131de213816Sad int
132de213816Sad pthread_kill(pthread_t thread, int sig)
133de213816Sad {
134de213816Sad 
135de213816Sad 	if ((sig < 0) || (sig >= _NSIG))
136de213816Sad 		return EINVAL;
137d9adedd7Sad 	if (pthread__find(thread) != 0)
138de213816Sad 		return ESRCH;
139*6d153667Sad 	if (_lwp_kill(thread->pt_lid, sig))
140*6d153667Sad 		return errno;
141*6d153667Sad 	return 0;
142de213816Sad }
143de213816Sad 
144de213816Sad int
145de213816Sad pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
146de213816Sad {
147de213816Sad 
148*6d153667Sad 	if (_sys___sigprocmask14(how, set, oset))
149*6d153667Sad 		return errno;
150*6d153667Sad 	return 0;
151de213816Sad }
152de213816Sad 
153de213816Sad int
154de213816Sad nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
155de213816Sad {
156de213816Sad 
157de213816Sad 	/*
158de213816Sad 	 * For now, just nanosleep.  In the future, maybe pass a ucontext_t
159de213816Sad 	 * to _lwp_nanosleep() and allow it to recycle our kernel stack.
160de213816Sad 	 */
161de213816Sad 	return  _sys_nanosleep(rqtp, rmtp);
162de213816Sad }
16366ac2ffaSad 
16466ac2ffaSad int
16566ac2ffaSad pthread__sched_yield(void)
16666ac2ffaSad {
16766ac2ffaSad 	pthread_t self;
16866ac2ffaSad 	int error;
16966ac2ffaSad 
17066ac2ffaSad 	self = pthread__self();
17166ac2ffaSad 
17266ac2ffaSad 	/* Memory barrier for unlocked mutex release. */
173a67e1e34Sad 	membar_producer();
17466ac2ffaSad 	self->pt_blocking++;
17566ac2ffaSad 	error = _sys_sched_yield();
17666ac2ffaSad 	self->pt_blocking--;
177a67e1e34Sad 	membar_sync();
17866ac2ffaSad 
17966ac2ffaSad 	return error;
18066ac2ffaSad }
181