1*7f19f937Sriastradh /* $NetBSD: pthread_misc.c,v 1.19 2022/04/10 10:38:33 riastradh 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*7f19f937Sriastradh __RCSID("$NetBSD: pthread_misc.c,v 1.19 2022/04/10 10:38:33 riastradh Exp $");
34f2e0628fSriastradh
35f2e0628fSriastradh /* Need to use libc-private names for atomic operations. */
36f2e0628fSriastradh #include "../../common/lib/libc/atomic/atomic_op_namespace.h"
375c71a4d4Srmind
385c71a4d4Srmind #include <errno.h>
395c71a4d4Srmind #include <string.h>
405c71a4d4Srmind #include <unistd.h>
41de213816Sad
42de213816Sad #include <sys/types.h>
435c71a4d4Srmind #include <sys/pset.h>
44de213816Sad #include <sys/signal.h>
45de213816Sad #include <sys/time.h>
46de213816Sad
47de213816Sad #include <lwp.h>
485c71a4d4Srmind #include <sched.h>
49de213816Sad
50de213816Sad #include "pthread.h"
51de213816Sad #include "pthread_int.h"
52173a7764Schristos #include "reentrant.h"
53de213816Sad
5466ac2ffaSad int pthread__sched_yield(void);
5566ac2ffaSad
56de213816Sad int _sys___sigprocmask14(int, const sigset_t *, sigset_t *);
5766ac2ffaSad int _sys_sched_yield(void);
58de213816Sad
__strong_alias(__libc_thr_sigsetmask,pthread_sigmask)59de213816Sad __strong_alias(__libc_thr_sigsetmask,pthread_sigmask)
60de213816Sad __strong_alias(__sigprocmask14,pthread_sigmask)
6166ac2ffaSad __strong_alias(__libc_thr_yield,pthread__sched_yield)
62de213816Sad
63de213816Sad int
64de213816Sad pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param)
65de213816Sad {
665c71a4d4Srmind
67004d6159Skamil pthread__error(EINVAL, "Invalid thread",
68004d6159Skamil thread->pt_magic == PT_MAGIC);
69004d6159Skamil
705c71a4d4Srmind if (pthread__find(thread) != 0)
715c71a4d4Srmind return ESRCH;
725c71a4d4Srmind
73603e4b9aSyamt if (_sched_getparam(getpid(), thread->pt_lid, policy, param) < 0)
74b5e9adddSrmind return errno;
75b5e9adddSrmind
76b5e9adddSrmind return 0;
77de213816Sad }
78de213816Sad
79de213816Sad int
pthread_setschedparam(pthread_t thread,int policy,const struct sched_param * param)80de213816Sad pthread_setschedparam(pthread_t thread, int policy,
81de213816Sad const struct sched_param *param)
82de213816Sad {
835c71a4d4Srmind struct sched_param sp;
845c71a4d4Srmind
85004d6159Skamil pthread__error(EINVAL, "Invalid thread",
86004d6159Skamil thread->pt_magic == PT_MAGIC);
87004d6159Skamil
885c71a4d4Srmind if (pthread__find(thread) != 0)
895c71a4d4Srmind return ESRCH;
905c71a4d4Srmind
915c71a4d4Srmind memcpy(&sp, param, sizeof(struct sched_param));
92603e4b9aSyamt if (_sched_setparam(getpid(), thread->pt_lid, policy, &sp) < 0)
93b5e9adddSrmind return errno;
94b5e9adddSrmind
95b5e9adddSrmind return 0;
965c71a4d4Srmind }
975c71a4d4Srmind
985c71a4d4Srmind int
pthread_getaffinity_np(pthread_t thread,size_t size,cpuset_t * cpuset)995c71a4d4Srmind pthread_getaffinity_np(pthread_t thread, size_t size, cpuset_t *cpuset)
1005c71a4d4Srmind {
1015c71a4d4Srmind
102004d6159Skamil pthread__error(EINVAL, "Invalid thread",
103004d6159Skamil thread->pt_magic == PT_MAGIC);
104004d6159Skamil
1055c71a4d4Srmind if (pthread__find(thread) != 0)
1065c71a4d4Srmind return ESRCH;
1075c71a4d4Srmind
108b5e9adddSrmind if (_sched_getaffinity(getpid(), thread->pt_lid, size, cpuset) < 0)
109b5e9adddSrmind return errno;
110b5e9adddSrmind
111b5e9adddSrmind return 0;
1125c71a4d4Srmind }
1135c71a4d4Srmind
1145c71a4d4Srmind int
pthread_setaffinity_np(pthread_t thread,size_t size,cpuset_t * cpuset)1155c71a4d4Srmind pthread_setaffinity_np(pthread_t thread, size_t size, cpuset_t *cpuset)
1165c71a4d4Srmind {
1175c71a4d4Srmind
118004d6159Skamil pthread__error(EINVAL, "Invalid thread",
119004d6159Skamil thread->pt_magic == PT_MAGIC);
120004d6159Skamil
1215c71a4d4Srmind if (pthread__find(thread) != 0)
1225c71a4d4Srmind return ESRCH;
1235c71a4d4Srmind
124b5e9adddSrmind if (_sched_setaffinity(getpid(), thread->pt_lid, size, cpuset) < 0)
125b5e9adddSrmind return errno;
126b5e9adddSrmind
127b5e9adddSrmind return 0;
1285c71a4d4Srmind }
1295c71a4d4Srmind
1305c71a4d4Srmind int
pthread_setschedprio(pthread_t thread,int prio)1315c71a4d4Srmind pthread_setschedprio(pthread_t thread, int prio)
1325c71a4d4Srmind {
1335c71a4d4Srmind struct sched_param sp;
1345c71a4d4Srmind
135004d6159Skamil pthread__error(EINVAL, "Invalid thread",
136004d6159Skamil thread->pt_magic == PT_MAGIC);
137004d6159Skamil
1385c71a4d4Srmind if (pthread__find(thread) != 0)
1395c71a4d4Srmind return ESRCH;
1405c71a4d4Srmind
1415c71a4d4Srmind sp.sched_priority = prio;
142603e4b9aSyamt if (_sched_setparam(getpid(), thread->pt_lid, SCHED_NONE, &sp) < 0)
143b5e9adddSrmind return errno;
144b5e9adddSrmind
145b5e9adddSrmind return 0;
146de213816Sad }
147de213816Sad
148de213816Sad int
pthread_kill(pthread_t thread,int sig)149de213816Sad pthread_kill(pthread_t thread, int sig)
150de213816Sad {
151de213816Sad
152004d6159Skamil pthread__error(EINVAL, "Invalid thread",
153004d6159Skamil thread->pt_magic == PT_MAGIC);
154004d6159Skamil
155de213816Sad if ((sig < 0) || (sig >= _NSIG))
156de213816Sad return EINVAL;
157d9adedd7Sad if (pthread__find(thread) != 0)
158de213816Sad return ESRCH;
1596d153667Sad if (_lwp_kill(thread->pt_lid, sig))
1606d153667Sad return errno;
1616d153667Sad return 0;
162de213816Sad }
163de213816Sad
164de213816Sad int
pthread_sigmask(int how,const sigset_t * set,sigset_t * oset)165de213816Sad pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
166de213816Sad {
1676d153667Sad if (_sys___sigprocmask14(how, set, oset))
1686d153667Sad return errno;
1696d153667Sad return 0;
170de213816Sad }
171de213816Sad
17266ac2ffaSad int
pthread__sched_yield(void)17366ac2ffaSad pthread__sched_yield(void)
17466ac2ffaSad {
17566ac2ffaSad
176173a7764Schristos if (__predict_false(__uselibcstub))
177173a7764Schristos return __libc_thr_yield();
178173a7764Schristos
179e99ed86bSad return _sys_sched_yield();
18066ac2ffaSad }
181