thr_attr.c revision 214335
1112918Sjeff/* 2112918Sjeff * Copyright (c) 2003 Craig Rodrigues <rodrigc@attbi.com>. 3112918Sjeff * All rights reserved. 4112918Sjeff * 5112918Sjeff * Redistribution and use in source and binary forms, with or without 6112918Sjeff * modification, are permitted provided that the following conditions 7112918Sjeff * are met: 8112918Sjeff * 1. Redistributions of source code must retain the above copyright 9112918Sjeff * notice, this list of conditions and the following disclaimer. 10112918Sjeff * 2. Redistributions in binary form must reproduce the above copyright 11112918Sjeff * notice, this list of conditions and the following disclaimer in the 12112918Sjeff * documentation and/or other materials provided with the distribution. 13112918Sjeff * 3. All advertising materials mentioning features or use of this software 14112918Sjeff * must display the following acknowledgement: 15112918Sjeff * This product includes software developed by Craig Rodrigues. 16112918Sjeff * 4. Neither the name of the author nor the names of any co-contributors 17112918Sjeff * may be used to endorse or promote products derived from this software 18112918Sjeff * without specific prior written permission. 19112918Sjeff * 20112918Sjeff * THIS SOFTWARE IS PROVIDED BY CRAIG RODRIGUES AND CONTRIBUTORS ``AS IS'' AND 21112918Sjeff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22112918Sjeff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23112918Sjeff * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24112918Sjeff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25112918Sjeff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26112918Sjeff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27112918Sjeff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28112918Sjeff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29112918Sjeff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30112918Sjeff * SUCH DAMAGE. 31112918Sjeff * 32112918Sjeff */ 33112918Sjeff 34112918Sjeff/* 35112918Sjeff * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. 36112918Sjeff * Copyright (C) 2001 Jason Evans <jasone@freebsd.org>. 37112918Sjeff * Copyright (c) 2002,2003 Alexey Zelkin <phantom@FreeBSD.org> 38112918Sjeff * All rights reserved. 39112918Sjeff * 40112918Sjeff * Redistribution and use in source and binary forms, with or without 41112918Sjeff * modification, are permitted provided that the following conditions 42112918Sjeff * are met: 43112918Sjeff * 1. Redistributions of source code must retain the above copyright 44112918Sjeff * notice(s), this list of conditions and the following disclaimer 45112918Sjeff * unmodified other than the allowable addition of one or more 46112918Sjeff * copyright notices. 47112918Sjeff * 2. Redistributions in binary form must reproduce the above copyright 48112918Sjeff * notice(s), this list of conditions and the following disclaimer in 49112918Sjeff * the documentation and/or other materials provided with the 50112918Sjeff * distribution. 51112918Sjeff * 52112918Sjeff * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY 53112918Sjeff * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54112918Sjeff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 55112918Sjeff * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE 56112918Sjeff * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 57112918Sjeff * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 58112918Sjeff * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 59112918Sjeff * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 60112918Sjeff * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 61112918Sjeff * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 62112918Sjeff * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 63112918Sjeff */ 64112918Sjeff 65144518Sdavidxu/* 66144518Sdavidxu * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>. 67144518Sdavidxu * All rights reserved. 68144518Sdavidxu * 69144518Sdavidxu * Redistribution and use in source and binary forms, with or without 70144518Sdavidxu * modification, are permitted provided that the following conditions 71144518Sdavidxu * are met: 72144518Sdavidxu * 1. Redistributions of source code must retain the above copyright 73144518Sdavidxu * notice, this list of conditions and the following disclaimer. 74144518Sdavidxu * 2. Redistributions in binary form must reproduce the above copyright 75144518Sdavidxu * notice, this list of conditions and the following disclaimer in the 76144518Sdavidxu * documentation and/or other materials provided with the distribution. 77165967Simp * 3. Neither the name of the author nor the names of any co-contributors 78144518Sdavidxu * may be used to endorse or promote products derived from this software 79144518Sdavidxu * without specific prior written permission. 80144518Sdavidxu * 81144518Sdavidxu * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND 82144518Sdavidxu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 83144518Sdavidxu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 84144518Sdavidxu * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 85144518Sdavidxu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 86144518Sdavidxu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 87144518Sdavidxu * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 88144518Sdavidxu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 89144518Sdavidxu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 90144518Sdavidxu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 91144518Sdavidxu * SUCH DAMAGE. 92144518Sdavidxu * 93144518Sdavidxu * $FreeBSD: head/lib/libthr/thread/thr_attr.c 214335 2010-10-25 11:16:50Z davidxu $ 94144518Sdavidxu */ 95112918Sjeff 96157457Sdavidxu#include "namespace.h" 97112918Sjeff#include <errno.h> 98112918Sjeff#include <pthread.h> 99112918Sjeff#include <stdlib.h> 100112918Sjeff#include <string.h> 101144518Sdavidxu#include <pthread_np.h> 102176815Sdavidxu#include <sys/sysctl.h> 103157457Sdavidxu#include "un-namespace.h" 104112918Sjeff 105112918Sjeff#include "thr_private.h" 106112918Sjeff 107214334Sdavidxustatic size_t _get_kern_cpuset_size(void); 108214334Sdavidxu 109125963Smtm__weak_reference(_pthread_attr_destroy, pthread_attr_destroy); 110112918Sjeff 111112918Sjeffint 112144518Sdavidxu_pthread_attr_destroy(pthread_attr_t *attr) 113112918Sjeff{ 114144518Sdavidxu int ret; 115112918Sjeff 116144518Sdavidxu /* Check for invalid arguments: */ 117144518Sdavidxu if (attr == NULL || *attr == NULL) 118144518Sdavidxu /* Invalid argument: */ 119144518Sdavidxu ret = EINVAL; 120144518Sdavidxu else { 121214334Sdavidxu if ((*attr)->cpuset != NULL) 122214334Sdavidxu free((*attr)->cpuset); 123144518Sdavidxu /* Free the memory allocated to the attribute object: */ 124144518Sdavidxu free(*attr); 125112918Sjeff 126144518Sdavidxu /* 127144518Sdavidxu * Leave the attribute pointer NULL now that the memory 128144518Sdavidxu * has been freed: 129144518Sdavidxu */ 130144518Sdavidxu *attr = NULL; 131144518Sdavidxu ret = 0; 132144518Sdavidxu } 133144518Sdavidxu return(ret); 134112918Sjeff} 135112918Sjeff 136144518Sdavidxu__weak_reference(_pthread_attr_get_np, pthread_attr_get_np); 137144518Sdavidxu 138112918Sjeffint 139214334Sdavidxu_pthread_attr_get_np(pthread_t pthread, pthread_attr_t *dstattr) 140112918Sjeff{ 141144518Sdavidxu struct pthread *curthread; 142214334Sdavidxu struct pthread_attr attr, *dst; 143144518Sdavidxu int ret; 144214334Sdavidxu size_t cpusetsize; 145144518Sdavidxu 146214335Sdavidxu if (pthread == NULL || dstattr == NULL || (dst = *dstattr) == NULL) 147112918Sjeff return (EINVAL); 148214334Sdavidxu cpusetsize = _get_kern_cpuset_size(); 149214334Sdavidxu if (dst->cpusetsize < cpusetsize) { 150214334Sdavidxu char *newset = realloc(dst->cpuset, cpusetsize); 151214334Sdavidxu if (newset == NULL) 152214334Sdavidxu return (errno); 153214334Sdavidxu memset(newset + dst->cpusetsize, 0, cpusetsize - 154214334Sdavidxu dst->cpusetsize); 155214334Sdavidxu dst->cpuset = (cpuset_t *)newset; 156214334Sdavidxu dst->cpusetsize = cpusetsize; 157214334Sdavidxu } 158144518Sdavidxu curthread = _get_curthread(); 159212536Sdavidxu if ((ret = _thr_find_thread(curthread, pthread, /*include dead*/0)) != 0) 160144518Sdavidxu return (ret); 161212536Sdavidxu attr = pthread->attr; 162212536Sdavidxu if (pthread->flags & THR_FLAGS_DETACHED) 163154126Sdavidxu attr.flags |= PTHREAD_DETACHED; 164214334Sdavidxu ret = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, TID(pthread), 165214334Sdavidxu dst->cpusetsize, dst->cpuset); 166214334Sdavidxu if (ret == -1) 167214334Sdavidxu ret = errno; 168212536Sdavidxu THR_THREAD_UNLOCK(curthread, pthread); 169214334Sdavidxu if (ret == 0) { 170214334Sdavidxu memcpy(&dst->pthread_attr_start_copy, 171214334Sdavidxu &attr.pthread_attr_start_copy, 172214334Sdavidxu offsetof(struct pthread_attr, pthread_attr_end_copy) - 173214334Sdavidxu offsetof(struct pthread_attr, pthread_attr_start_copy)); 174214334Sdavidxu } 175214334Sdavidxu return (ret); 176112918Sjeff} 177112918Sjeff 178144518Sdavidxu__weak_reference(_pthread_attr_getdetachstate, pthread_attr_getdetachstate); 179144518Sdavidxu 180112918Sjeffint 181144518Sdavidxu_pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate) 182112918Sjeff{ 183144518Sdavidxu int ret; 184144518Sdavidxu 185144518Sdavidxu /* Check for invalid arguments: */ 186144518Sdavidxu if (attr == NULL || *attr == NULL || detachstate == NULL) 187144518Sdavidxu ret = EINVAL; 188144518Sdavidxu else { 189144518Sdavidxu /* Check if the detached flag is set: */ 190144518Sdavidxu if ((*attr)->flags & PTHREAD_DETACHED) 191144518Sdavidxu /* Return detached: */ 192144518Sdavidxu *detachstate = PTHREAD_CREATE_DETACHED; 193144518Sdavidxu else 194144518Sdavidxu /* Return joinable: */ 195144518Sdavidxu *detachstate = PTHREAD_CREATE_JOINABLE; 196144518Sdavidxu ret = 0; 197112918Sjeff } 198144518Sdavidxu return(ret); 199112918Sjeff} 200112918Sjeff 201144518Sdavidxu__weak_reference(_pthread_attr_getguardsize, pthread_attr_getguardsize); 202144518Sdavidxu 203112918Sjeffint 204144518Sdavidxu_pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize) 205112918Sjeff{ 206144518Sdavidxu int ret; 207112918Sjeff 208144518Sdavidxu /* Check for invalid arguments: */ 209144518Sdavidxu if (attr == NULL || *attr == NULL || guardsize == NULL) 210144518Sdavidxu ret = EINVAL; 211144518Sdavidxu else { 212144518Sdavidxu /* Return the guard size: */ 213144518Sdavidxu *guardsize = (*attr)->guardsize_attr; 214144518Sdavidxu ret = 0; 215144518Sdavidxu } 216144518Sdavidxu return(ret); 217112918Sjeff} 218112918Sjeff 219144518Sdavidxu__weak_reference(_pthread_attr_getinheritsched, pthread_attr_getinheritsched); 220144518Sdavidxu 221112918Sjeffint 222144518Sdavidxu_pthread_attr_getinheritsched(const pthread_attr_t *attr, int *sched_inherit) 223112918Sjeff{ 224144518Sdavidxu int ret = 0; 225112918Sjeff 226144518Sdavidxu if ((attr == NULL) || (*attr == NULL)) 227144518Sdavidxu ret = EINVAL; 228144518Sdavidxu else 229144518Sdavidxu *sched_inherit = (*attr)->sched_inherit; 230112918Sjeff 231144518Sdavidxu return(ret); 232112918Sjeff} 233112918Sjeff 234144518Sdavidxu__weak_reference(_pthread_attr_getschedparam, pthread_attr_getschedparam); 235144518Sdavidxu 236112918Sjeffint 237144518Sdavidxu_pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param) 238112918Sjeff{ 239144518Sdavidxu int ret = 0; 240112918Sjeff 241144518Sdavidxu if ((attr == NULL) || (*attr == NULL) || (param == NULL)) 242144518Sdavidxu ret = EINVAL; 243144518Sdavidxu else 244144518Sdavidxu param->sched_priority = (*attr)->prio; 245112918Sjeff 246144518Sdavidxu return(ret); 247112918Sjeff} 248112918Sjeff 249144518Sdavidxu__weak_reference(_pthread_attr_getschedpolicy, pthread_attr_getschedpolicy); 250144518Sdavidxu 251112918Sjeffint 252144518Sdavidxu_pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy) 253112918Sjeff{ 254144518Sdavidxu int ret = 0; 255112918Sjeff 256144518Sdavidxu if ((attr == NULL) || (*attr == NULL) || (policy == NULL)) 257144518Sdavidxu ret = EINVAL; 258144518Sdavidxu else 259144518Sdavidxu *policy = (*attr)->sched_policy; 260112918Sjeff 261144518Sdavidxu return(ret); 262144518Sdavidxu} 263112918Sjeff 264144518Sdavidxu__weak_reference(_pthread_attr_getscope, pthread_attr_getscope); 265112918Sjeff 266112918Sjeffint 267144518Sdavidxu_pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope) 268112918Sjeff{ 269144518Sdavidxu int ret = 0; 270112918Sjeff 271144518Sdavidxu if ((attr == NULL) || (*attr == NULL) || (contentionscope == NULL)) 272144518Sdavidxu /* Return an invalid argument: */ 273144518Sdavidxu ret = EINVAL; 274112918Sjeff 275144518Sdavidxu else 276144518Sdavidxu *contentionscope = (*attr)->flags & PTHREAD_SCOPE_SYSTEM ? 277144518Sdavidxu PTHREAD_SCOPE_SYSTEM : PTHREAD_SCOPE_PROCESS; 278112918Sjeff 279144518Sdavidxu return(ret); 280112918Sjeff} 281112918Sjeff 282144518Sdavidxu__weak_reference(_pthread_attr_getstack, pthread_attr_getstack); 283144518Sdavidxu 284112918Sjeffint 285144518Sdavidxu_pthread_attr_getstack(const pthread_attr_t * __restrict attr, 286144518Sdavidxu void ** __restrict stackaddr, 287144518Sdavidxu size_t * __restrict stacksize) 288112918Sjeff{ 289144518Sdavidxu int ret; 290112918Sjeff 291144518Sdavidxu /* Check for invalid arguments: */ 292144518Sdavidxu if (attr == NULL || *attr == NULL || stackaddr == NULL 293144518Sdavidxu || stacksize == NULL ) 294144518Sdavidxu ret = EINVAL; 295144518Sdavidxu else { 296144518Sdavidxu /* Return the stack address and size */ 297144518Sdavidxu *stackaddr = (*attr)->stackaddr_attr; 298144518Sdavidxu *stacksize = (*attr)->stacksize_attr; 299144518Sdavidxu ret = 0; 300144518Sdavidxu } 301144518Sdavidxu return(ret); 302144518Sdavidxu} 303112918Sjeff 304144518Sdavidxu__weak_reference(_pthread_attr_getstackaddr, pthread_attr_getstackaddr); 305112918Sjeff 306112918Sjeffint 307144518Sdavidxu_pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr) 308112918Sjeff{ 309144518Sdavidxu int ret; 310112918Sjeff 311144518Sdavidxu /* Check for invalid arguments: */ 312144518Sdavidxu if (attr == NULL || *attr == NULL || stackaddr == NULL) 313144518Sdavidxu ret = EINVAL; 314144518Sdavidxu else { 315144518Sdavidxu /* Return the stack address: */ 316144518Sdavidxu *stackaddr = (*attr)->stackaddr_attr; 317144518Sdavidxu ret = 0; 318144518Sdavidxu } 319144518Sdavidxu return(ret); 320112918Sjeff} 321112918Sjeff 322144518Sdavidxu__weak_reference(_pthread_attr_getstacksize, pthread_attr_getstacksize); 323144518Sdavidxu 324112918Sjeffint 325144518Sdavidxu_pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize) 326112918Sjeff{ 327144518Sdavidxu int ret; 328112918Sjeff 329144518Sdavidxu /* Check for invalid arguments: */ 330144518Sdavidxu if (attr == NULL || *attr == NULL || stacksize == NULL) 331144518Sdavidxu ret = EINVAL; 332144518Sdavidxu else { 333144518Sdavidxu /* Return the stack size: */ 334144518Sdavidxu *stacksize = (*attr)->stacksize_attr; 335144518Sdavidxu ret = 0; 336144518Sdavidxu } 337144518Sdavidxu return(ret); 338112918Sjeff} 339112918Sjeff 340144518Sdavidxu__weak_reference(_pthread_attr_init, pthread_attr_init); 341144518Sdavidxu 342112918Sjeffint 343144518Sdavidxu_pthread_attr_init(pthread_attr_t *attr) 344112918Sjeff{ 345144518Sdavidxu int ret; 346144518Sdavidxu pthread_attr_t pattr; 347112918Sjeff 348144518Sdavidxu _thr_check_init(); 349112918Sjeff 350144518Sdavidxu /* Allocate memory for the attribute object: */ 351144518Sdavidxu if ((pattr = (pthread_attr_t) malloc(sizeof(struct pthread_attr))) == NULL) 352144518Sdavidxu /* Insufficient memory: */ 353144518Sdavidxu ret = ENOMEM; 354144518Sdavidxu else { 355144518Sdavidxu /* Initialise the attribute object with the defaults: */ 356144518Sdavidxu memcpy(pattr, &_pthread_attr_default, sizeof(struct pthread_attr)); 357144518Sdavidxu 358144518Sdavidxu /* Return a pointer to the attribute object: */ 359144518Sdavidxu *attr = pattr; 360144518Sdavidxu ret = 0; 361144518Sdavidxu } 362144518Sdavidxu return(ret); 363112918Sjeff} 364112918Sjeff 365144518Sdavidxu__weak_reference(_pthread_attr_setcreatesuspend_np, pthread_attr_setcreatesuspend_np); 366144518Sdavidxu 367112918Sjeffint 368144518Sdavidxu_pthread_attr_setcreatesuspend_np(pthread_attr_t *attr) 369112918Sjeff{ 370112918Sjeff int ret; 371112918Sjeff 372144518Sdavidxu if (attr == NULL || *attr == NULL) { 373144518Sdavidxu ret = EINVAL; 374144518Sdavidxu } else { 375144518Sdavidxu (*attr)->suspend = THR_CREATE_SUSPENDED; 376144518Sdavidxu ret = 0; 377144518Sdavidxu } 378144518Sdavidxu return(ret); 379144518Sdavidxu} 380112918Sjeff 381144518Sdavidxu__weak_reference(_pthread_attr_setdetachstate, pthread_attr_setdetachstate); 382112918Sjeff 383112918Sjeffint 384144518Sdavidxu_pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) 385112918Sjeff{ 386144518Sdavidxu int ret; 387112918Sjeff 388144518Sdavidxu /* Check for invalid arguments: */ 389144518Sdavidxu if (attr == NULL || *attr == NULL || 390144518Sdavidxu (detachstate != PTHREAD_CREATE_DETACHED && 391144518Sdavidxu detachstate != PTHREAD_CREATE_JOINABLE)) 392144518Sdavidxu ret = EINVAL; 393144518Sdavidxu else { 394144518Sdavidxu /* Check if detached state: */ 395144518Sdavidxu if (detachstate == PTHREAD_CREATE_DETACHED) 396144518Sdavidxu /* Set the detached flag: */ 397144518Sdavidxu (*attr)->flags |= PTHREAD_DETACHED; 398144518Sdavidxu else 399144518Sdavidxu /* Reset the detached flag: */ 400144518Sdavidxu (*attr)->flags &= ~PTHREAD_DETACHED; 401144518Sdavidxu ret = 0; 402144518Sdavidxu } 403144518Sdavidxu return(ret); 404144518Sdavidxu} 405112918Sjeff 406144518Sdavidxu__weak_reference(_pthread_attr_setguardsize, pthread_attr_setguardsize); 407112918Sjeff 408112918Sjeffint 409144518Sdavidxu_pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) 410112918Sjeff{ 411144518Sdavidxu int ret; 412112918Sjeff 413144518Sdavidxu /* Check for invalid arguments. */ 414144518Sdavidxu if (attr == NULL || *attr == NULL) 415144518Sdavidxu ret = EINVAL; 416144518Sdavidxu else { 417144518Sdavidxu /* Save the stack size. */ 418144518Sdavidxu (*attr)->guardsize_attr = guardsize; 419144518Sdavidxu ret = 0; 420144518Sdavidxu } 421144518Sdavidxu return(ret); 422112918Sjeff} 423112918Sjeff 424144518Sdavidxu__weak_reference(_pthread_attr_setinheritsched, pthread_attr_setinheritsched); 425144518Sdavidxu 426112918Sjeffint 427144518Sdavidxu_pthread_attr_setinheritsched(pthread_attr_t *attr, int sched_inherit) 428112918Sjeff{ 429144518Sdavidxu int ret = 0; 430112918Sjeff 431144518Sdavidxu if ((attr == NULL) || (*attr == NULL)) 432144518Sdavidxu ret = EINVAL; 433144518Sdavidxu else if (sched_inherit != PTHREAD_INHERIT_SCHED && 434144518Sdavidxu sched_inherit != PTHREAD_EXPLICIT_SCHED) 435144518Sdavidxu ret = ENOTSUP; 436144518Sdavidxu else 437144518Sdavidxu (*attr)->sched_inherit = sched_inherit; 438112918Sjeff 439144518Sdavidxu return(ret); 440112918Sjeff} 441112918Sjeff 442144518Sdavidxu__weak_reference(_pthread_attr_setschedparam, pthread_attr_setschedparam); 443144518Sdavidxu 444112918Sjeffint 445144518Sdavidxu_pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param) 446112918Sjeff{ 447158073Sdavidxu int policy; 448112918Sjeff 449144518Sdavidxu if ((attr == NULL) || (*attr == NULL)) 450158073Sdavidxu return (EINVAL); 451112918Sjeff 452158073Sdavidxu if (param == NULL) 453158073Sdavidxu return (ENOTSUP); 454158073Sdavidxu 455158073Sdavidxu policy = (*attr)->sched_policy; 456158073Sdavidxu 457160287Sdavidxu if (policy == SCHED_FIFO || policy == SCHED_RR) { 458160287Sdavidxu if (param->sched_priority < _thr_priorities[policy-1].pri_min || 459160287Sdavidxu param->sched_priority > _thr_priorities[policy-1].pri_max) 460158073Sdavidxu return (ENOTSUP); 461160287Sdavidxu } else { 462160287Sdavidxu /* 463160287Sdavidxu * Ignore it for SCHED_OTHER now, patches for glib ports 464160287Sdavidxu * are wrongly using M:N thread library's internal macro 465160287Sdavidxu * THR_MIN_PRIORITY and THR_MAX_PRIORITY. 466160287Sdavidxu */ 467160287Sdavidxu } 468158073Sdavidxu 469158073Sdavidxu (*attr)->prio = param->sched_priority; 470158073Sdavidxu 471158073Sdavidxu return (0); 472112918Sjeff} 473112918Sjeff 474144518Sdavidxu__weak_reference(_pthread_attr_setschedpolicy, pthread_attr_setschedpolicy); 475144518Sdavidxu 476112918Sjeffint 477144518Sdavidxu_pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy) 478112918Sjeff{ 479144518Sdavidxu int ret = 0; 480112918Sjeff 481144518Sdavidxu if ((attr == NULL) || (*attr == NULL)) 482144518Sdavidxu ret = EINVAL; 483144518Sdavidxu else if ((policy < SCHED_FIFO) || (policy > SCHED_RR)) { 484144518Sdavidxu ret = ENOTSUP; 485158073Sdavidxu } else { 486144518Sdavidxu (*attr)->sched_policy = policy; 487158073Sdavidxu (*attr)->prio = _thr_priorities[policy-1].pri_default; 488158073Sdavidxu } 489144518Sdavidxu return(ret); 490112918Sjeff} 491112918Sjeff 492144518Sdavidxu__weak_reference(_pthread_attr_setscope, pthread_attr_setscope); 493144518Sdavidxu 494112918Sjeffint 495144518Sdavidxu_pthread_attr_setscope(pthread_attr_t *attr, int contentionscope) 496112918Sjeff{ 497144518Sdavidxu int ret = 0; 498112918Sjeff 499144518Sdavidxu if ((attr == NULL) || (*attr == NULL)) { 500144518Sdavidxu /* Return an invalid argument: */ 501144518Sdavidxu ret = EINVAL; 502144518Sdavidxu } else if ((contentionscope != PTHREAD_SCOPE_PROCESS) && 503144518Sdavidxu (contentionscope != PTHREAD_SCOPE_SYSTEM)) { 504144518Sdavidxu ret = EINVAL; 505144518Sdavidxu } else if (contentionscope == PTHREAD_SCOPE_SYSTEM) { 506144518Sdavidxu (*attr)->flags |= contentionscope; 507144518Sdavidxu } else { 508144518Sdavidxu (*attr)->flags &= ~PTHREAD_SCOPE_SYSTEM; 509144518Sdavidxu } 510144518Sdavidxu return (ret); 511112918Sjeff} 512112918Sjeff 513144518Sdavidxu__weak_reference(_pthread_attr_setstack, pthread_attr_setstack); 514144518Sdavidxu 515112918Sjeffint 516144518Sdavidxu_pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, 517144518Sdavidxu size_t stacksize) 518112918Sjeff{ 519144518Sdavidxu int ret; 520144518Sdavidxu 521144518Sdavidxu /* Check for invalid arguments: */ 522112918Sjeff if (attr == NULL || *attr == NULL || stackaddr == NULL 523144518Sdavidxu || stacksize < PTHREAD_STACK_MIN) 524144518Sdavidxu ret = EINVAL; 525144518Sdavidxu else { 526144518Sdavidxu /* Save the stack address and stack size */ 527144518Sdavidxu (*attr)->stackaddr_attr = stackaddr; 528144518Sdavidxu (*attr)->stacksize_attr = stacksize; 529144518Sdavidxu ret = 0; 530144518Sdavidxu } 531144518Sdavidxu return(ret); 532144518Sdavidxu} 533112918Sjeff 534144518Sdavidxu__weak_reference(_pthread_attr_setstackaddr, pthread_attr_setstackaddr); 535112918Sjeff 536112918Sjeffint 537144518Sdavidxu_pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr) 538112918Sjeff{ 539144518Sdavidxu int ret; 540144518Sdavidxu 541144518Sdavidxu /* Check for invalid arguments: */ 542112918Sjeff if (attr == NULL || *attr == NULL || stackaddr == NULL) 543144518Sdavidxu ret = EINVAL; 544144518Sdavidxu else { 545144518Sdavidxu /* Save the stack address: */ 546144518Sdavidxu (*attr)->stackaddr_attr = stackaddr; 547144518Sdavidxu ret = 0; 548144518Sdavidxu } 549144518Sdavidxu return(ret); 550144518Sdavidxu} 551112918Sjeff 552144518Sdavidxu__weak_reference(_pthread_attr_setstacksize, pthread_attr_setstacksize); 553112918Sjeff 554112918Sjeffint 555144518Sdavidxu_pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) 556112918Sjeff{ 557144518Sdavidxu int ret; 558112918Sjeff 559144518Sdavidxu /* Check for invalid arguments: */ 560144518Sdavidxu if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN) 561144518Sdavidxu ret = EINVAL; 562144518Sdavidxu else { 563144518Sdavidxu /* Save the stack size: */ 564144518Sdavidxu (*attr)->stacksize_attr = stacksize; 565144518Sdavidxu ret = 0; 566144518Sdavidxu } 567144518Sdavidxu return(ret); 568112918Sjeff} 569176781Sdavidxu 570177605Srustatic size_t 571177605Sru_get_kern_cpuset_size(void) 572176815Sdavidxu{ 573176815Sdavidxu static int kern_cpuset_size = 0; 574176815Sdavidxu 575176815Sdavidxu if (kern_cpuset_size == 0) { 576177605Sru size_t len; 577176815Sdavidxu 578176815Sdavidxu len = sizeof(kern_cpuset_size); 579176815Sdavidxu if (sysctlbyname("kern.smp.maxcpus", &kern_cpuset_size, 580176815Sdavidxu &len, NULL, 0)) 581176815Sdavidxu PANIC("failed to get sysctl kern.smp.maxcpus"); 582176815Sdavidxu 583176815Sdavidxu kern_cpuset_size = (kern_cpuset_size + 7) / 8; 584176815Sdavidxu } 585176815Sdavidxu 586176815Sdavidxu return (kern_cpuset_size); 587176815Sdavidxu} 588176815Sdavidxu 589176815Sdavidxu__weak_reference(_pthread_attr_setaffinity_np, pthread_attr_setaffinity_np); 590176781Sdavidxuint 591176815Sdavidxu_pthread_attr_setaffinity_np(pthread_attr_t *pattr, size_t cpusetsize, 592178446Sdelphij const cpuset_t *cpusetp) 593176781Sdavidxu{ 594176781Sdavidxu pthread_attr_t attr; 595176781Sdavidxu int ret; 596176781Sdavidxu 597176781Sdavidxu if (pattr == NULL || (attr = (*pattr)) == NULL) 598176781Sdavidxu ret = EINVAL; 599176781Sdavidxu else { 600178446Sdelphij if (cpusetsize == 0 || cpusetp == NULL) { 601176781Sdavidxu if (attr->cpuset != NULL) { 602176781Sdavidxu free(attr->cpuset); 603176781Sdavidxu attr->cpuset = NULL; 604176781Sdavidxu attr->cpusetsize = 0; 605176781Sdavidxu } 606176781Sdavidxu return (0); 607176781Sdavidxu } 608176781Sdavidxu 609176815Sdavidxu if (cpusetsize > attr->cpusetsize) { 610177605Sru size_t kern_size = _get_kern_cpuset_size(); 611176815Sdavidxu if (cpusetsize > kern_size) { 612177605Sru size_t i; 613176815Sdavidxu for (i = kern_size; i < cpusetsize; ++i) { 614178446Sdelphij if (((char *)cpusetp)[i]) 615176815Sdavidxu return (EINVAL); 616176815Sdavidxu } 617176815Sdavidxu } 618176781Sdavidxu void *newset = realloc(attr->cpuset, cpusetsize); 619176781Sdavidxu if (newset == NULL) 620176781Sdavidxu return (ENOMEM); 621176781Sdavidxu attr->cpuset = newset; 622176781Sdavidxu attr->cpusetsize = cpusetsize; 623176815Sdavidxu } else { 624176815Sdavidxu memset(((char *)attr->cpuset) + cpusetsize, 0, 625176864Sdavidxu attr->cpusetsize - cpusetsize); 626176815Sdavidxu attr->cpusetsize = cpusetsize; 627176781Sdavidxu } 628178446Sdelphij memcpy(attr->cpuset, cpusetp, cpusetsize); 629176781Sdavidxu ret = 0; 630176781Sdavidxu } 631176781Sdavidxu return (ret); 632176781Sdavidxu} 633176781Sdavidxu 634176815Sdavidxu__weak_reference(_pthread_attr_getaffinity_np, pthread_attr_getaffinity_np); 635176781Sdavidxuint 636176815Sdavidxu_pthread_attr_getaffinity_np(const pthread_attr_t *pattr, size_t cpusetsize, 637178446Sdelphij cpuset_t *cpusetp) 638176781Sdavidxu{ 639176781Sdavidxu pthread_attr_t attr; 640176781Sdavidxu int ret = 0; 641176781Sdavidxu 642176781Sdavidxu if (pattr == NULL || (attr = (*pattr)) == NULL) 643176781Sdavidxu ret = EINVAL; 644176781Sdavidxu else if (attr->cpuset != NULL) { 645178446Sdelphij memcpy(cpusetp, attr->cpuset, MIN(cpusetsize, attr->cpusetsize)); 646176781Sdavidxu if (cpusetsize > attr->cpusetsize) 647178446Sdelphij memset(((char *)cpusetp) + attr->cpusetsize, 0, 648176781Sdavidxu cpusetsize - attr->cpusetsize); 649176781Sdavidxu } else { 650177605Sru size_t kern_size = _get_kern_cpuset_size(); 651178446Sdelphij memset(cpusetp, -1, MIN(cpusetsize, kern_size)); 652176815Sdavidxu if (cpusetsize > kern_size) 653178446Sdelphij memset(((char *)cpusetp) + kern_size, 0, 654176815Sdavidxu cpusetsize - kern_size); 655176781Sdavidxu } 656176781Sdavidxu return (ret); 657176781Sdavidxu} 658