xref: /netbsd/lib/libpthread/pthread_misc.c (revision 603e4b9a)
1*603e4b9aSyamt /*	$NetBSD: pthread_misc.c,v 1.6 2008/02/09 17:07:54 yamt 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  * 3. All advertising materials mentioning features or use of this software
19de213816Sad  *    must display the following acknowledgement:
20de213816Sad  *        This product includes software developed by the NetBSD
21de213816Sad  *        Foundation, Inc. and its contributors.
22de213816Sad  * 4. Neither the name of The NetBSD Foundation nor the names of its
23de213816Sad  *    contributors may be used to endorse or promote products derived
24de213816Sad  *    from this software without specific prior written permission.
25de213816Sad  *
26de213816Sad  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27de213816Sad  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28de213816Sad  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29de213816Sad  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30de213816Sad  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31de213816Sad  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32de213816Sad  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33de213816Sad  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34de213816Sad  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35de213816Sad  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36de213816Sad  * POSSIBILITY OF SUCH DAMAGE.
37de213816Sad  */
38de213816Sad 
39de213816Sad #include <sys/cdefs.h>
40*603e4b9aSyamt __RCSID("$NetBSD: pthread_misc.c,v 1.6 2008/02/09 17:07:54 yamt Exp $");
415c71a4d4Srmind 
425c71a4d4Srmind #include <errno.h>
435c71a4d4Srmind #include <string.h>
445c71a4d4Srmind #include <unistd.h>
45de213816Sad 
46de213816Sad #include <sys/types.h>
475c71a4d4Srmind #include <sys/pset.h>
48de213816Sad #include <sys/signal.h>
49de213816Sad #include <sys/time.h>
50de213816Sad 
51de213816Sad #include <lwp.h>
525c71a4d4Srmind #include <sched.h>
53de213816Sad 
54de213816Sad #include "pthread.h"
55de213816Sad #include "pthread_int.h"
56de213816Sad 
5766ac2ffaSad int	pthread__sched_yield(void);
5866ac2ffaSad 
59de213816Sad int	_sys___sigprocmask14(int, const sigset_t *, sigset_t *);
60de213816Sad int	_sys_nanosleep(const struct timespec *, struct timespec *);
6166ac2ffaSad int	_sys_sched_yield(void);
62de213816Sad 
63de213816Sad __strong_alias(_nanosleep, nanosleep)
64de213816Sad __strong_alias(__libc_thr_sigsetmask,pthread_sigmask)
65de213816Sad __strong_alias(__sigprocmask14,pthread_sigmask)
6666ac2ffaSad __strong_alias(__libc_thr_yield,pthread__sched_yield)
67de213816Sad 
68de213816Sad int
69de213816Sad pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param)
70de213816Sad {
715c71a4d4Srmind 
725c71a4d4Srmind 	if (pthread__find(thread) != 0)
735c71a4d4Srmind 		return ESRCH;
745c71a4d4Srmind 
75*603e4b9aSyamt 	if (_sched_getparam(getpid(), thread->pt_lid, policy, param) < 0)
76b5e9adddSrmind 		return errno;
77b5e9adddSrmind 
78b5e9adddSrmind 	return 0;
79de213816Sad }
80de213816Sad 
81de213816Sad int
82de213816Sad pthread_setschedparam(pthread_t thread, int policy,
83de213816Sad     const struct sched_param *param)
84de213816Sad {
855c71a4d4Srmind 	struct sched_param sp;
865c71a4d4Srmind 
875c71a4d4Srmind 	if (pthread__find(thread) != 0)
885c71a4d4Srmind 		return ESRCH;
895c71a4d4Srmind 
905c71a4d4Srmind 	memcpy(&sp, param, sizeof(struct sched_param));
91*603e4b9aSyamt 	if (_sched_setparam(getpid(), thread->pt_lid, policy, &sp) < 0)
92b5e9adddSrmind 		return errno;
93b5e9adddSrmind 
94b5e9adddSrmind 	return 0;
955c71a4d4Srmind }
965c71a4d4Srmind 
975c71a4d4Srmind int
985c71a4d4Srmind pthread_getaffinity_np(pthread_t thread, size_t size, cpuset_t *cpuset)
995c71a4d4Srmind {
1005c71a4d4Srmind 
1015c71a4d4Srmind 	if (pthread__find(thread) != 0)
1025c71a4d4Srmind 		return ESRCH;
1035c71a4d4Srmind 
104b5e9adddSrmind 	if (_sched_getaffinity(getpid(), thread->pt_lid, size, cpuset) < 0)
105b5e9adddSrmind 		return errno;
106b5e9adddSrmind 
107b5e9adddSrmind 	return 0;
1085c71a4d4Srmind }
1095c71a4d4Srmind 
1105c71a4d4Srmind int
1115c71a4d4Srmind pthread_setaffinity_np(pthread_t thread, size_t size, cpuset_t *cpuset)
1125c71a4d4Srmind {
1135c71a4d4Srmind 
1145c71a4d4Srmind 	if (pthread__find(thread) != 0)
1155c71a4d4Srmind 		return ESRCH;
1165c71a4d4Srmind 
117b5e9adddSrmind 	if (_sched_setaffinity(getpid(), thread->pt_lid, size, cpuset) < 0)
118b5e9adddSrmind 		return errno;
119b5e9adddSrmind 
120b5e9adddSrmind 	return 0;
1215c71a4d4Srmind }
1225c71a4d4Srmind 
1235c71a4d4Srmind int
1245c71a4d4Srmind pthread_setschedprio(pthread_t thread, int prio)
1255c71a4d4Srmind {
1265c71a4d4Srmind 	struct sched_param sp;
1275c71a4d4Srmind 
1285c71a4d4Srmind 	if (pthread__find(thread) != 0)
1295c71a4d4Srmind 		return ESRCH;
1305c71a4d4Srmind 
1315c71a4d4Srmind 	sp.sched_priority = prio;
132*603e4b9aSyamt 	if (_sched_setparam(getpid(), thread->pt_lid, SCHED_NONE, &sp) < 0)
133b5e9adddSrmind 		return errno;
134b5e9adddSrmind 
135b5e9adddSrmind 	return 0;
136de213816Sad }
137de213816Sad 
138de213816Sad int
139de213816Sad pthread_kill(pthread_t thread, int sig)
140de213816Sad {
141de213816Sad 
142de213816Sad 	if ((sig < 0) || (sig >= _NSIG))
143de213816Sad 		return EINVAL;
144d9adedd7Sad 	if (pthread__find(thread) != 0)
145de213816Sad 		return ESRCH;
146de213816Sad 
147de213816Sad 	return _lwp_kill(thread->pt_lid, sig);
148de213816Sad }
149de213816Sad 
150de213816Sad int
151de213816Sad pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
152de213816Sad {
153de213816Sad 
154de213816Sad 	return _sys___sigprocmask14(how, set, oset);
155de213816Sad }
156de213816Sad 
157de213816Sad int
158de213816Sad nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
159de213816Sad {
160de213816Sad 
161de213816Sad 	/*
162de213816Sad 	 * For now, just nanosleep.  In the future, maybe pass a ucontext_t
163de213816Sad 	 * to _lwp_nanosleep() and allow it to recycle our kernel stack.
164de213816Sad 	 */
165de213816Sad 	return  _sys_nanosleep(rqtp, rmtp);
166de213816Sad }
16766ac2ffaSad 
16866ac2ffaSad int
16966ac2ffaSad pthread__sched_yield(void)
17066ac2ffaSad {
17166ac2ffaSad 	pthread_t self;
17266ac2ffaSad 	int error;
17366ac2ffaSad 
17466ac2ffaSad 	self = pthread__self();
17566ac2ffaSad 
17666ac2ffaSad #ifdef PTHREAD__HAVE_ATOMIC
17766ac2ffaSad 	/* Memory barrier for unlocked mutex release. */
17866ac2ffaSad 	pthread__membar_producer();
17966ac2ffaSad #endif
18066ac2ffaSad 	self->pt_blocking++;
18166ac2ffaSad 	error = _sys_sched_yield();
18266ac2ffaSad 	self->pt_blocking--;
18366ac2ffaSad 
18466ac2ffaSad 	return error;
18566ac2ffaSad }
186