thr_attr.c revision 214335
159612Sjasone/* 259612Sjasone * Copyright (c) 2003 Craig Rodrigues <rodrigc@attbi.com>. 359612Sjasone * All rights reserved. 459612Sjasone * 559612Sjasone * Redistribution and use in source and binary forms, with or without 659612Sjasone * modification, are permitted provided that the following conditions 759612Sjasone * are met: 859612Sjasone * 1. Redistributions of source code must retain the above copyright 959612Sjasone * notice, this list of conditions and the following disclaimer. 1059612Sjasone * 2. Redistributions in binary form must reproduce the above copyright 1159612Sjasone * notice, this list of conditions and the following disclaimer in the 1259612Sjasone * documentation and/or other materials provided with the distribution. 1359612Sjasone * 3. All advertising materials mentioning features or use of this software 1459612Sjasone * must display the following acknowledgement: 1559612Sjasone * This product includes software developed by Craig Rodrigues. 1659612Sjasone * 4. Neither the name of the author nor the names of any co-contributors 1759612Sjasone * may be used to endorse or promote products derived from this software 1859612Sjasone * without specific prior written permission. 1959612Sjasone * 2059612Sjasone * THIS SOFTWARE IS PROVIDED BY CRAIG RODRIGUES AND CONTRIBUTORS ``AS IS'' AND 2159612Sjasone * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2259612Sjasone * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2359612Sjasone * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2459612Sjasone * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2559612Sjasone * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2659612Sjasone * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2759612Sjasone * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2859612Sjasone * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2959612Sjasone * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3059612Sjasone * SUCH DAMAGE. 3159612Sjasone * 3259612Sjasone */ 3359612Sjasone 3459612Sjasone/* 3559612Sjasone * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. 3659612Sjasone * Copyright (C) 2001 Jason Evans <jasone@freebsd.org>. 3759612Sjasone * Copyright (c) 2002,2003 Alexey Zelkin <phantom@FreeBSD.org> 3859612Sjasone * All rights reserved. 3959612Sjasone * 4059612Sjasone * Redistribution and use in source and binary forms, with or without 4159612Sjasone * modification, are permitted provided that the following conditions 4259612Sjasone * are met: 4359612Sjasone * 1. Redistributions of source code must retain the above copyright 4459612Sjasone * notice(s), this list of conditions and the following disclaimer 4559612Sjasone * unmodified other than the allowable addition of one or more 4659612Sjasone * copyright notices. 4759612Sjasone * 2. Redistributions in binary form must reproduce the above copyright 4859612Sjasone * notice(s), this list of conditions and the following disclaimer in 4959612Sjasone * the documentation and/or other materials provided with the 5059612Sjasone * distribution. 5159612Sjasone * 5259612Sjasone * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY 5359612Sjasone * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 5459612Sjasone * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 5559612Sjasone * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE 5659612Sjasone * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 5759612Sjasone * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 5859612Sjasone * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 5959612Sjasone * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 6059612Sjasone * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 6159612Sjasone * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 6281975Skris * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 6381975Skris */ 6481975Skris 6559612Sjasone/* 6659612Sjasone * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>. 6759612Sjasone * All rights reserved. 6859612Sjasone * 6959612Sjasone * Redistribution and use in source and binary forms, with or without 7059612Sjasone * modification, are permitted provided that the following conditions 7159612Sjasone * are met: 7259612Sjasone * 1. Redistributions of source code must retain the above copyright 7359612Sjasone * notice, this list of conditions and the following disclaimer. 7459612Sjasone * 2. Redistributions in binary form must reproduce the above copyright 7559612Sjasone * notice, this list of conditions and the following disclaimer in the 7659612Sjasone * documentation and/or other materials provided with the distribution. 7759612Sjasone * 3. Neither the name of the author nor the names of any co-contributors 7859612Sjasone * may be used to endorse or promote products derived from this software 7959612Sjasone * without specific prior written permission. 8059612Sjasone * 8159612Sjasone * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND 8259612Sjasone * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 8359612Sjasone * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 8459612Sjasone * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 8559612Sjasone * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 8659612Sjasone * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 8759612Sjasone * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 8859612Sjasone * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 8959612Sjasone * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 9059612Sjasone * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 9159612Sjasone * SUCH DAMAGE. 9259612Sjasone * 9359612Sjasone * $FreeBSD: head/lib/libthr/thread/thr_attr.c 214335 2010-10-25 11:16:50Z davidxu $ 9459612Sjasone */ 9559612Sjasone 9659612Sjasone#include "namespace.h" 9759612Sjasone#include <errno.h> 9859612Sjasone#include <pthread.h> 9959612Sjasone#include <stdlib.h> 10059612Sjasone#include <string.h> 10159612Sjasone#include <pthread_np.h> 10259612Sjasone#include <sys/sysctl.h> 10359612Sjasone#include "un-namespace.h" 10459612Sjasone 10559612Sjasone#include "thr_private.h" 10659612Sjasone 10759612Sjasonestatic size_t _get_kern_cpuset_size(void); 10859612Sjasone 10959612Sjasone__weak_reference(_pthread_attr_destroy, pthread_attr_destroy); 11059612Sjasone 11159612Sjasoneint 11259612Sjasone_pthread_attr_destroy(pthread_attr_t *attr) 11359612Sjasone{ 11459612Sjasone int ret; 11559612Sjasone 11659612Sjasone /* Check for invalid arguments: */ 11759612Sjasone if (attr == NULL || *attr == NULL) 11859612Sjasone /* Invalid argument: */ 11959612Sjasone ret = EINVAL; 12059612Sjasone else { 12159612Sjasone if ((*attr)->cpuset != NULL) 12259612Sjasone free((*attr)->cpuset); 12359612Sjasone /* Free the memory allocated to the attribute object: */ 12459612Sjasone free(*attr); 12559612Sjasone 12659612Sjasone /* 12759612Sjasone * Leave the attribute pointer NULL now that the memory 12859612Sjasone * has been freed: 12959612Sjasone */ 13059612Sjasone *attr = NULL; 13159612Sjasone ret = 0; 13259612Sjasone } 13359612Sjasone return(ret); 13459612Sjasone} 13559612Sjasone 13659612Sjasone__weak_reference(_pthread_attr_get_np, pthread_attr_get_np); 13759612Sjasone 13859612Sjasoneint 13959612Sjasone_pthread_attr_get_np(pthread_t pthread, pthread_attr_t *dstattr) 14059612Sjasone{ 14159612Sjasone struct pthread *curthread; 14259612Sjasone struct pthread_attr attr, *dst; 14359612Sjasone int ret; 14459612Sjasone size_t cpusetsize; 14559612Sjasone 14659612Sjasone if (pthread == NULL || dstattr == NULL || (dst = *dstattr) == NULL) 14759612Sjasone return (EINVAL); 14859612Sjasone cpusetsize = _get_kern_cpuset_size(); 14959612Sjasone if (dst->cpusetsize < cpusetsize) { 15059612Sjasone char *newset = realloc(dst->cpuset, cpusetsize); 15159612Sjasone if (newset == NULL) 15259612Sjasone return (errno); 15359612Sjasone memset(newset + dst->cpusetsize, 0, cpusetsize - 15459612Sjasone dst->cpusetsize); 15559612Sjasone dst->cpuset = (cpuset_t *)newset; 15659612Sjasone dst->cpusetsize = cpusetsize; 15759612Sjasone } 15859612Sjasone curthread = _get_curthread(); 15959612Sjasone if ((ret = _thr_find_thread(curthread, pthread, /*include dead*/0)) != 0) 16059612Sjasone return (ret); 16159612Sjasone attr = pthread->attr; 16259612Sjasone if (pthread->flags & THR_FLAGS_DETACHED) 16359612Sjasone attr.flags |= PTHREAD_DETACHED; 16459612Sjasone ret = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, TID(pthread), 16559612Sjasone dst->cpusetsize, dst->cpuset); 16659612Sjasone if (ret == -1) 16759612Sjasone ret = errno; 16899239Sdeischen THR_THREAD_UNLOCK(curthread, pthread); 16959612Sjasone if (ret == 0) { 17059612Sjasone memcpy(&dst->pthread_attr_start_copy, 17159612Sjasone &attr.pthread_attr_start_copy, 17259612Sjasone offsetof(struct pthread_attr, pthread_attr_end_copy) - 17359612Sjasone offsetof(struct pthread_attr, pthread_attr_start_copy)); 17459612Sjasone } 17559612Sjasone return (ret); 17659612Sjasone} 17759612Sjasone 17859612Sjasone__weak_reference(_pthread_attr_getdetachstate, pthread_attr_getdetachstate); 17959612Sjasone 18059612Sjasoneint 18159612Sjasone_pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate) 18259612Sjasone{ 18359612Sjasone int ret; 18459612Sjasone 18559612Sjasone /* Check for invalid arguments: */ 18659612Sjasone if (attr == NULL || *attr == NULL || detachstate == NULL) 18759612Sjasone ret = EINVAL; 18859612Sjasone else { 18959612Sjasone /* Check if the detached flag is set: */ 19059612Sjasone if ((*attr)->flags & PTHREAD_DETACHED) 19159612Sjasone /* Return detached: */ 19259612Sjasone *detachstate = PTHREAD_CREATE_DETACHED; 19359612Sjasone else 19459612Sjasone /* Return joinable: */ 19559612Sjasone *detachstate = PTHREAD_CREATE_JOINABLE; 19659612Sjasone ret = 0; 19759612Sjasone } 19859612Sjasone return(ret); 19959612Sjasone} 20059612Sjasone 20159612Sjasone__weak_reference(_pthread_attr_getguardsize, pthread_attr_getguardsize); 20259612Sjasone 20359612Sjasoneint 20459612Sjasone_pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize) 20559612Sjasone{ 20659612Sjasone int ret; 20759612Sjasone 20859612Sjasone /* Check for invalid arguments: */ 20959612Sjasone if (attr == NULL || *attr == NULL || guardsize == NULL) 21059612Sjasone ret = EINVAL; 21159612Sjasone else { 21259612Sjasone /* Return the guard size: */ 21359612Sjasone *guardsize = (*attr)->guardsize_attr; 21459612Sjasone ret = 0; 21559612Sjasone } 21659612Sjasone return(ret); 21759612Sjasone} 21859612Sjasone 21959612Sjasone__weak_reference(_pthread_attr_getinheritsched, pthread_attr_getinheritsched); 22059612Sjasone 22159612Sjasoneint 22259612Sjasone_pthread_attr_getinheritsched(const pthread_attr_t *attr, int *sched_inherit) 22359612Sjasone{ 22459612Sjasone int ret = 0; 22559612Sjasone 22659612Sjasone if ((attr == NULL) || (*attr == NULL)) 22759612Sjasone ret = EINVAL; 22859612Sjasone else 22959612Sjasone *sched_inherit = (*attr)->sched_inherit; 23059612Sjasone 23159612Sjasone return(ret); 23259612Sjasone} 23359612Sjasone 23459612Sjasone__weak_reference(_pthread_attr_getschedparam, pthread_attr_getschedparam); 23559612Sjasone 23659612Sjasoneint 23759612Sjasone_pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param) 23859612Sjasone{ 23959612Sjasone int ret = 0; 24059612Sjasone 24159612Sjasone if ((attr == NULL) || (*attr == NULL) || (param == NULL)) 24259612Sjasone ret = EINVAL; 24359612Sjasone else 24459612Sjasone param->sched_priority = (*attr)->prio; 24559612Sjasone 24659612Sjasone return(ret); 24759612Sjasone} 24859612Sjasone 24959612Sjasone__weak_reference(_pthread_attr_getschedpolicy, pthread_attr_getschedpolicy); 25059612Sjasone 25159612Sjasoneint 25259612Sjasone_pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy) 25359612Sjasone{ 25459612Sjasone int ret = 0; 25559612Sjasone 25659612Sjasone if ((attr == NULL) || (*attr == NULL) || (policy == NULL)) 25759612Sjasone ret = EINVAL; 25859612Sjasone else 25959612Sjasone *policy = (*attr)->sched_policy; 26059612Sjasone 26159612Sjasone return(ret); 26259612Sjasone} 26359612Sjasone 26459612Sjasone__weak_reference(_pthread_attr_getscope, pthread_attr_getscope); 26559612Sjasone 26659612Sjasoneint 26759612Sjasone_pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope) 26859612Sjasone{ 26959612Sjasone int ret = 0; 27059612Sjasone 27159612Sjasone if ((attr == NULL) || (*attr == NULL) || (contentionscope == NULL)) 27259612Sjasone /* Return an invalid argument: */ 27359612Sjasone ret = EINVAL; 27459612Sjasone 27559612Sjasone else 27659612Sjasone *contentionscope = (*attr)->flags & PTHREAD_SCOPE_SYSTEM ? 27759612Sjasone PTHREAD_SCOPE_SYSTEM : PTHREAD_SCOPE_PROCESS; 27859612Sjasone 27959612Sjasone return(ret); 28059612Sjasone} 28159612Sjasone 28259612Sjasone__weak_reference(_pthread_attr_getstack, pthread_attr_getstack); 28359612Sjasone 28459612Sjasoneint 28559612Sjasone_pthread_attr_getstack(const pthread_attr_t * __restrict attr, 28659612Sjasone void ** __restrict stackaddr, 28759612Sjasone size_t * __restrict stacksize) 28859612Sjasone{ 28959612Sjasone int ret; 29059612Sjasone 29159612Sjasone /* Check for invalid arguments: */ 29259612Sjasone if (attr == NULL || *attr == NULL || stackaddr == NULL 29359612Sjasone || stacksize == NULL ) 29459612Sjasone ret = EINVAL; 29559612Sjasone else { 29659612Sjasone /* Return the stack address and size */ 29759612Sjasone *stackaddr = (*attr)->stackaddr_attr; 29859612Sjasone *stacksize = (*attr)->stacksize_attr; 29959612Sjasone ret = 0; 30059612Sjasone } 30159612Sjasone return(ret); 30259612Sjasone} 30359612Sjasone 30459612Sjasone__weak_reference(_pthread_attr_getstackaddr, pthread_attr_getstackaddr); 30559612Sjasone 30659612Sjasoneint 30759612Sjasone_pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr) 30859612Sjasone{ 30959612Sjasone int ret; 31059612Sjasone 31159612Sjasone /* Check for invalid arguments: */ 31259612Sjasone if (attr == NULL || *attr == NULL || stackaddr == NULL) 31359612Sjasone ret = EINVAL; 31459612Sjasone else { 31559612Sjasone /* Return the stack address: */ 31659612Sjasone *stackaddr = (*attr)->stackaddr_attr; 31759612Sjasone ret = 0; 31859612Sjasone } 31959612Sjasone return(ret); 32059612Sjasone} 32159612Sjasone 32259612Sjasone__weak_reference(_pthread_attr_getstacksize, pthread_attr_getstacksize); 32359612Sjasone 32459612Sjasoneint 32559612Sjasone_pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize) 32659612Sjasone{ 32759612Sjasone int ret; 32859612Sjasone 32959612Sjasone /* Check for invalid arguments: */ 33059612Sjasone if (attr == NULL || *attr == NULL || stacksize == NULL) 33159612Sjasone ret = EINVAL; 33259612Sjasone else { 33359612Sjasone /* Return the stack size: */ 33459612Sjasone *stacksize = (*attr)->stacksize_attr; 33559612Sjasone ret = 0; 33659612Sjasone } 33759612Sjasone return(ret); 33859612Sjasone} 33959612Sjasone 34059612Sjasone__weak_reference(_pthread_attr_init, pthread_attr_init); 34159612Sjasone 34259612Sjasoneint 34359612Sjasone_pthread_attr_init(pthread_attr_t *attr) 34459612Sjasone{ 34559612Sjasone int ret; 34659612Sjasone pthread_attr_t pattr; 34759612Sjasone 34859612Sjasone _thr_check_init(); 34959612Sjasone 35059612Sjasone /* Allocate memory for the attribute object: */ 35159612Sjasone if ((pattr = (pthread_attr_t) malloc(sizeof(struct pthread_attr))) == NULL) 35259612Sjasone /* Insufficient memory: */ 35359612Sjasone ret = ENOMEM; 35459612Sjasone else { 35559612Sjasone /* Initialise the attribute object with the defaults: */ 35659612Sjasone memcpy(pattr, &_pthread_attr_default, sizeof(struct pthread_attr)); 35799239Sdeischen 35859612Sjasone /* Return a pointer to the attribute object: */ 35959612Sjasone *attr = pattr; 36059612Sjasone ret = 0; 36159612Sjasone } 36259612Sjasone return(ret); 36359612Sjasone} 36459612Sjasone 36559612Sjasone__weak_reference(_pthread_attr_setcreatesuspend_np, pthread_attr_setcreatesuspend_np); 36659612Sjasone 36759612Sjasoneint 36859612Sjasone_pthread_attr_setcreatesuspend_np(pthread_attr_t *attr) 36959612Sjasone{ 37059612Sjasone int ret; 37159612Sjasone 37259612Sjasone if (attr == NULL || *attr == NULL) { 37359612Sjasone ret = EINVAL; 37459612Sjasone } else { 37559612Sjasone (*attr)->suspend = THR_CREATE_SUSPENDED; 37659612Sjasone ret = 0; 37759612Sjasone } 37859612Sjasone return(ret); 37959612Sjasone} 38059612Sjasone 38159612Sjasone__weak_reference(_pthread_attr_setdetachstate, pthread_attr_setdetachstate); 38259612Sjasone 38359612Sjasoneint 38459612Sjasone_pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) 38559612Sjasone{ 38659612Sjasone int ret; 38759612Sjasone 38859612Sjasone /* Check for invalid arguments: */ 38959612Sjasone if (attr == NULL || *attr == NULL || 39059612Sjasone (detachstate != PTHREAD_CREATE_DETACHED && 39159612Sjasone detachstate != PTHREAD_CREATE_JOINABLE)) 39259612Sjasone ret = EINVAL; 39359612Sjasone else { 39459612Sjasone /* Check if detached state: */ 39559612Sjasone if (detachstate == PTHREAD_CREATE_DETACHED) 39659612Sjasone /* Set the detached flag: */ 39759612Sjasone (*attr)->flags |= PTHREAD_DETACHED; 39859612Sjasone else 39959612Sjasone /* Reset the detached flag: */ 40059612Sjasone (*attr)->flags &= ~PTHREAD_DETACHED; 40159612Sjasone ret = 0; 40259612Sjasone } 40359612Sjasone return(ret); 40459612Sjasone} 40559612Sjasone 40659612Sjasone__weak_reference(_pthread_attr_setguardsize, pthread_attr_setguardsize); 40759612Sjasone 40859612Sjasoneint 40959612Sjasone_pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) 41059612Sjasone{ 41159612Sjasone int ret; 41259612Sjasone 41359612Sjasone /* Check for invalid arguments. */ 41459612Sjasone if (attr == NULL || *attr == NULL) 41559612Sjasone ret = EINVAL; 41659612Sjasone else { 41759612Sjasone /* Save the stack size. */ 41859612Sjasone (*attr)->guardsize_attr = guardsize; 41959612Sjasone ret = 0; 42059612Sjasone } 42159612Sjasone return(ret); 42259612Sjasone} 42359612Sjasone 42459612Sjasone__weak_reference(_pthread_attr_setinheritsched, pthread_attr_setinheritsched); 42559612Sjasone 42659612Sjasoneint 42759612Sjasone_pthread_attr_setinheritsched(pthread_attr_t *attr, int sched_inherit) 42859612Sjasone{ 42959612Sjasone int ret = 0; 43059612Sjasone 43159612Sjasone if ((attr == NULL) || (*attr == NULL)) 43259612Sjasone ret = EINVAL; 43359612Sjasone else if (sched_inherit != PTHREAD_INHERIT_SCHED && 43459612Sjasone sched_inherit != PTHREAD_EXPLICIT_SCHED) 43559612Sjasone ret = ENOTSUP; 43659612Sjasone else 43759612Sjasone (*attr)->sched_inherit = sched_inherit; 43859612Sjasone 43959612Sjasone return(ret); 44059612Sjasone} 44159612Sjasone 44259612Sjasone__weak_reference(_pthread_attr_setschedparam, pthread_attr_setschedparam); 44359612Sjasone 44459612Sjasoneint 44559612Sjasone_pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param) 44659612Sjasone{ 44759612Sjasone int policy; 44859612Sjasone 44959612Sjasone if ((attr == NULL) || (*attr == NULL)) 45059612Sjasone return (EINVAL); 45159612Sjasone 45259612Sjasone if (param == NULL) 45359612Sjasone return (ENOTSUP); 45459612Sjasone 45559612Sjasone policy = (*attr)->sched_policy; 45659612Sjasone 45759612Sjasone if (policy == SCHED_FIFO || policy == SCHED_RR) { 45859612Sjasone if (param->sched_priority < _thr_priorities[policy-1].pri_min || 45959612Sjasone param->sched_priority > _thr_priorities[policy-1].pri_max) 46059612Sjasone return (ENOTSUP); 46159612Sjasone } else { 46259612Sjasone /* 46359612Sjasone * Ignore it for SCHED_OTHER now, patches for glib ports 46459612Sjasone * are wrongly using M:N thread library's internal macro 46559612Sjasone * THR_MIN_PRIORITY and THR_MAX_PRIORITY. 46659612Sjasone */ 46759612Sjasone } 46859612Sjasone 46959612Sjasone (*attr)->prio = param->sched_priority; 47059612Sjasone 47159612Sjasone return (0); 47259612Sjasone} 47359612Sjasone 47459612Sjasone__weak_reference(_pthread_attr_setschedpolicy, pthread_attr_setschedpolicy); 47559612Sjasone 47659612Sjasoneint 47759612Sjasone_pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy) 47859612Sjasone{ 47959612Sjasone int ret = 0; 48059612Sjasone 48159612Sjasone if ((attr == NULL) || (*attr == NULL)) 48259612Sjasone ret = EINVAL; 48359612Sjasone else if ((policy < SCHED_FIFO) || (policy > SCHED_RR)) { 48459612Sjasone ret = ENOTSUP; 48559612Sjasone } else { 48659612Sjasone (*attr)->sched_policy = policy; 48759612Sjasone (*attr)->prio = _thr_priorities[policy-1].pri_default; 48859612Sjasone } 48959612Sjasone return(ret); 49059612Sjasone} 49159612Sjasone 49259612Sjasone__weak_reference(_pthread_attr_setscope, pthread_attr_setscope); 49359612Sjasone 49459612Sjasoneint 49559612Sjasone_pthread_attr_setscope(pthread_attr_t *attr, int contentionscope) 49659612Sjasone{ 49759612Sjasone int ret = 0; 49859612Sjasone 49959612Sjasone if ((attr == NULL) || (*attr == NULL)) { 50059612Sjasone /* Return an invalid argument: */ 50159612Sjasone ret = EINVAL; 50259612Sjasone } else if ((contentionscope != PTHREAD_SCOPE_PROCESS) && 50359612Sjasone (contentionscope != PTHREAD_SCOPE_SYSTEM)) { 50459612Sjasone ret = EINVAL; 50559612Sjasone } else if (contentionscope == PTHREAD_SCOPE_SYSTEM) { 50659612Sjasone (*attr)->flags |= contentionscope; 50759612Sjasone } else { 50859612Sjasone (*attr)->flags &= ~PTHREAD_SCOPE_SYSTEM; 50959612Sjasone } 51059612Sjasone return (ret); 51159612Sjasone} 51259612Sjasone 51359612Sjasone__weak_reference(_pthread_attr_setstack, pthread_attr_setstack); 51459612Sjasone 51559612Sjasoneint 51659612Sjasone_pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, 51759612Sjasone size_t stacksize) 51859612Sjasone{ 51959612Sjasone int ret; 52059612Sjasone 52159612Sjasone /* Check for invalid arguments: */ 52259612Sjasone if (attr == NULL || *attr == NULL || stackaddr == NULL 52359612Sjasone || stacksize < PTHREAD_STACK_MIN) 52459612Sjasone ret = EINVAL; 52559612Sjasone else { 52659612Sjasone /* Save the stack address and stack size */ 52759612Sjasone (*attr)->stackaddr_attr = stackaddr; 52859612Sjasone (*attr)->stacksize_attr = stacksize; 52959612Sjasone ret = 0; 53059612Sjasone } 53159612Sjasone return(ret); 53259612Sjasone} 53359612Sjasone 53459612Sjasone__weak_reference(_pthread_attr_setstackaddr, pthread_attr_setstackaddr); 53559612Sjasone 53659612Sjasoneint 53759612Sjasone_pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr) 53859612Sjasone{ 53959612Sjasone int ret; 54059612Sjasone 54159612Sjasone /* Check for invalid arguments: */ 54259612Sjasone if (attr == NULL || *attr == NULL || stackaddr == NULL) 54359612Sjasone ret = EINVAL; 54459612Sjasone else { 54559612Sjasone /* Save the stack address: */ 54659612Sjasone (*attr)->stackaddr_attr = stackaddr; 54759612Sjasone ret = 0; 54859612Sjasone } 54959612Sjasone return(ret); 55059612Sjasone} 55159612Sjasone 55259612Sjasone__weak_reference(_pthread_attr_setstacksize, pthread_attr_setstacksize); 55359612Sjasone 55459612Sjasoneint 55559612Sjasone_pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) 55659612Sjasone{ 55759612Sjasone int ret; 55859612Sjasone 55959612Sjasone /* Check for invalid arguments: */ 56059612Sjasone if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN) 56159612Sjasone ret = EINVAL; 56259612Sjasone else { 56359612Sjasone /* Save the stack size: */ 56459612Sjasone (*attr)->stacksize_attr = stacksize; 56559612Sjasone ret = 0; 56659612Sjasone } 56759612Sjasone return(ret); 56859612Sjasone} 56959612Sjasone 57059612Sjasonestatic size_t 57159612Sjasone_get_kern_cpuset_size(void) 57259612Sjasone{ 57359612Sjasone static int kern_cpuset_size = 0; 57459612Sjasone 57559612Sjasone if (kern_cpuset_size == 0) { 57659612Sjasone size_t len; 57759612Sjasone 57859612Sjasone len = sizeof(kern_cpuset_size); 57959612Sjasone if (sysctlbyname("kern.smp.maxcpus", &kern_cpuset_size, 58059612Sjasone &len, NULL, 0)) 58159612Sjasone PANIC("failed to get sysctl kern.smp.maxcpus"); 58259612Sjasone 58359612Sjasone kern_cpuset_size = (kern_cpuset_size + 7) / 8; 58459612Sjasone } 58559612Sjasone 58659612Sjasone return (kern_cpuset_size); 58759612Sjasone} 58859612Sjasone 58959612Sjasone__weak_reference(_pthread_attr_setaffinity_np, pthread_attr_setaffinity_np); 59059612Sjasoneint 59159612Sjasone_pthread_attr_setaffinity_np(pthread_attr_t *pattr, size_t cpusetsize, 59259612Sjasone const cpuset_t *cpusetp) 59359612Sjasone{ 59459612Sjasone pthread_attr_t attr; 59559612Sjasone int ret; 59659612Sjasone 59759612Sjasone if (pattr == NULL || (attr = (*pattr)) == NULL) 59859612Sjasone ret = EINVAL; 59959612Sjasone else { 60059612Sjasone if (cpusetsize == 0 || cpusetp == NULL) { 60159612Sjasone if (attr->cpuset != NULL) { 60259612Sjasone free(attr->cpuset); 60359612Sjasone attr->cpuset = NULL; 60459612Sjasone attr->cpusetsize = 0; 60559612Sjasone } 60659612Sjasone return (0); 60759612Sjasone } 60859612Sjasone 60959612Sjasone if (cpusetsize > attr->cpusetsize) { 61059612Sjasone size_t kern_size = _get_kern_cpuset_size(); 61159612Sjasone if (cpusetsize > kern_size) { 61259612Sjasone size_t i; 61359612Sjasone for (i = kern_size; i < cpusetsize; ++i) { 61459612Sjasone if (((char *)cpusetp)[i]) 61559612Sjasone return (EINVAL); 61659612Sjasone } 61759612Sjasone } 61859612Sjasone void *newset = realloc(attr->cpuset, cpusetsize); 61959612Sjasone if (newset == NULL) 62059612Sjasone return (ENOMEM); 62159612Sjasone attr->cpuset = newset; 62259612Sjasone attr->cpusetsize = cpusetsize; 62359612Sjasone } else { 62459612Sjasone memset(((char *)attr->cpuset) + cpusetsize, 0, 62559612Sjasone attr->cpusetsize - cpusetsize); 62659612Sjasone attr->cpusetsize = cpusetsize; 62759612Sjasone } 62859612Sjasone memcpy(attr->cpuset, cpusetp, cpusetsize); 62959612Sjasone ret = 0; 63059612Sjasone } 63159612Sjasone return (ret); 63259612Sjasone} 63359612Sjasone 63459612Sjasone__weak_reference(_pthread_attr_getaffinity_np, pthread_attr_getaffinity_np); 63559612Sjasoneint 63659612Sjasone_pthread_attr_getaffinity_np(const pthread_attr_t *pattr, size_t cpusetsize, 63759612Sjasone cpuset_t *cpusetp) 63859612Sjasone{ 63959612Sjasone pthread_attr_t attr; 64059612Sjasone int ret = 0; 64159612Sjasone 64259612Sjasone if (pattr == NULL || (attr = (*pattr)) == NULL) 64359612Sjasone ret = EINVAL; 64459612Sjasone else if (attr->cpuset != NULL) { 64559612Sjasone memcpy(cpusetp, attr->cpuset, MIN(cpusetsize, attr->cpusetsize)); 64659612Sjasone if (cpusetsize > attr->cpusetsize) 64759612Sjasone memset(((char *)cpusetp) + attr->cpusetsize, 0, 64859612Sjasone cpusetsize - attr->cpusetsize); 64959612Sjasone } else { 65059612Sjasone size_t kern_size = _get_kern_cpuset_size(); 65159612Sjasone memset(cpusetp, -1, MIN(cpusetsize, kern_size)); 65259612Sjasone if (cpusetsize > kern_size) 65359612Sjasone memset(((char *)cpusetp) + kern_size, 0, 65459612Sjasone cpusetsize - kern_size); 65559612Sjasone } 65659612Sjasone return (ret); 65759612Sjasone} 65859612Sjasone