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