1bb535300SJeff Roberson /* 2bb535300SJeff Roberson * Copyright (c) 2003 Craig Rodrigues <rodrigc@attbi.com>. 3bb535300SJeff Roberson * All rights reserved. 4bb535300SJeff Roberson * 5bb535300SJeff Roberson * Redistribution and use in source and binary forms, with or without 6bb535300SJeff Roberson * modification, are permitted provided that the following conditions 7bb535300SJeff Roberson * are met: 8bb535300SJeff Roberson * 1. Redistributions of source code must retain the above copyright 9bb535300SJeff Roberson * notice, this list of conditions and the following disclaimer. 10bb535300SJeff Roberson * 2. Redistributions in binary form must reproduce the above copyright 11bb535300SJeff Roberson * notice, this list of conditions and the following disclaimer in the 12bb535300SJeff Roberson * documentation and/or other materials provided with the distribution. 13bb535300SJeff Roberson * 3. All advertising materials mentioning features or use of this software 14bb535300SJeff Roberson * must display the following acknowledgement: 15bb535300SJeff Roberson * This product includes software developed by Craig Rodrigues. 16bb535300SJeff Roberson * 4. Neither the name of the author nor the names of any co-contributors 17bb535300SJeff Roberson * may be used to endorse or promote products derived from this software 18bb535300SJeff Roberson * without specific prior written permission. 19bb535300SJeff Roberson * 20bb535300SJeff Roberson * THIS SOFTWARE IS PROVIDED BY CRAIG RODRIGUES AND CONTRIBUTORS ``AS IS'' AND 21bb535300SJeff Roberson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22bb535300SJeff Roberson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23bb535300SJeff Roberson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24bb535300SJeff Roberson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25bb535300SJeff Roberson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26bb535300SJeff Roberson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27bb535300SJeff Roberson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28bb535300SJeff Roberson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29bb535300SJeff Roberson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30bb535300SJeff Roberson * SUCH DAMAGE. 31bb535300SJeff Roberson * 32bb535300SJeff Roberson */ 33bb535300SJeff Roberson 34bb535300SJeff Roberson /* 35bb535300SJeff Roberson * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. 36bb535300SJeff Roberson * Copyright (C) 2001 Jason Evans <jasone@freebsd.org>. 37bb535300SJeff Roberson * Copyright (c) 2002,2003 Alexey Zelkin <phantom@FreeBSD.org> 38bb535300SJeff Roberson * All rights reserved. 39bb535300SJeff Roberson * 40bb535300SJeff Roberson * Redistribution and use in source and binary forms, with or without 41bb535300SJeff Roberson * modification, are permitted provided that the following conditions 42bb535300SJeff Roberson * are met: 43bb535300SJeff Roberson * 1. Redistributions of source code must retain the above copyright 44bb535300SJeff Roberson * notice(s), this list of conditions and the following disclaimer 45bb535300SJeff Roberson * unmodified other than the allowable addition of one or more 46bb535300SJeff Roberson * copyright notices. 47bb535300SJeff Roberson * 2. Redistributions in binary form must reproduce the above copyright 48bb535300SJeff Roberson * notice(s), this list of conditions and the following disclaimer in 49bb535300SJeff Roberson * the documentation and/or other materials provided with the 50bb535300SJeff Roberson * distribution. 51bb535300SJeff Roberson * 52bb535300SJeff Roberson * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY 53bb535300SJeff Roberson * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54bb535300SJeff Roberson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 55bb535300SJeff Roberson * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE 56bb535300SJeff Roberson * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 57bb535300SJeff Roberson * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 58bb535300SJeff Roberson * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 59bb535300SJeff Roberson * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 60bb535300SJeff Roberson * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 61bb535300SJeff Roberson * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 62bb535300SJeff Roberson * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 63bb535300SJeff Roberson */ 64bb535300SJeff Roberson 65a091d823SDavid Xu /* 66a091d823SDavid Xu * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>. 67a091d823SDavid Xu * All rights reserved. 68a091d823SDavid Xu * 69a091d823SDavid Xu * Redistribution and use in source and binary forms, with or without 70a091d823SDavid Xu * modification, are permitted provided that the following conditions 71a091d823SDavid Xu * are met: 72a091d823SDavid Xu * 1. Redistributions of source code must retain the above copyright 73a091d823SDavid Xu * notice, this list of conditions and the following disclaimer. 74a091d823SDavid Xu * 2. Redistributions in binary form must reproduce the above copyright 75a091d823SDavid Xu * notice, this list of conditions and the following disclaimer in the 76a091d823SDavid Xu * documentation and/or other materials provided with the distribution. 77fed32d75SWarner Losh * 3. Neither the name of the author nor the names of any co-contributors 78a091d823SDavid Xu * may be used to endorse or promote products derived from this software 79a091d823SDavid Xu * without specific prior written permission. 80a091d823SDavid Xu * 81a091d823SDavid Xu * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND 82a091d823SDavid Xu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 83a091d823SDavid Xu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 84a091d823SDavid Xu * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 85a091d823SDavid Xu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 86a091d823SDavid Xu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 87a091d823SDavid Xu * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 88a091d823SDavid Xu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 89a091d823SDavid Xu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 90a091d823SDavid Xu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 91a091d823SDavid Xu * SUCH DAMAGE. 92a091d823SDavid Xu * 93a091d823SDavid Xu * $FreeBSD$ 94a091d823SDavid Xu */ 95bb535300SJeff Roberson 9637a6356bSDavid Xu #include "namespace.h" 97bb535300SJeff Roberson #include <errno.h> 98bb535300SJeff Roberson #include <pthread.h> 99bb535300SJeff Roberson #include <stdlib.h> 100bb535300SJeff Roberson #include <string.h> 101a091d823SDavid Xu #include <pthread_np.h> 10221845eb9SDavid Xu #include <sys/sysctl.h> 10337a6356bSDavid Xu #include "un-namespace.h" 104bb535300SJeff Roberson 105bb535300SJeff Roberson #include "thr_private.h" 106bb535300SJeff Roberson 1070d48409fSMike Makonnen __weak_reference(_pthread_attr_destroy, pthread_attr_destroy); 108bb535300SJeff Roberson 109bb535300SJeff Roberson int 110bb535300SJeff Roberson _pthread_attr_destroy(pthread_attr_t *attr) 111bb535300SJeff Roberson { 112a091d823SDavid Xu int ret; 113bb535300SJeff Roberson 114a091d823SDavid Xu /* Check for invalid arguments: */ 115a091d823SDavid Xu if (attr == NULL || *attr == NULL) 116a091d823SDavid Xu /* Invalid argument: */ 117a091d823SDavid Xu ret = EINVAL; 118a091d823SDavid Xu else { 119a091d823SDavid Xu /* Free the memory allocated to the attribute object: */ 120bb535300SJeff Roberson free(*attr); 121a091d823SDavid Xu 122a091d823SDavid Xu /* 123a091d823SDavid Xu * Leave the attribute pointer NULL now that the memory 124a091d823SDavid Xu * has been freed: 125a091d823SDavid Xu */ 126bb535300SJeff Roberson *attr = NULL; 127a091d823SDavid Xu ret = 0; 128a091d823SDavid Xu } 129a091d823SDavid Xu return(ret); 130bb535300SJeff Roberson } 131bb535300SJeff Roberson 132a091d823SDavid Xu __weak_reference(_pthread_attr_get_np, pthread_attr_get_np); 133bb535300SJeff Roberson 134bb535300SJeff Roberson int 135*a9b764e2SDavid Xu _pthread_attr_get_np(pthread_t pthread, pthread_attr_t *dst) 136bb535300SJeff Roberson { 137a091d823SDavid Xu struct pthread *curthread; 138a091d823SDavid Xu struct pthread_attr attr; 139bb535300SJeff Roberson int ret; 140bb535300SJeff Roberson 141*a9b764e2SDavid Xu if (pthread == NULL || dst == NULL || *dst == NULL) 142bb535300SJeff Roberson return (EINVAL); 143bb535300SJeff Roberson 144a091d823SDavid Xu curthread = _get_curthread(); 145*a9b764e2SDavid Xu if ((ret = _thr_find_thread(curthread, pthread, /*include dead*/0)) != 0) 146bb535300SJeff Roberson return (ret); 147*a9b764e2SDavid Xu attr = pthread->attr; 148*a9b764e2SDavid Xu if (pthread->flags & THR_FLAGS_DETACHED) 1494160cda0SDavid Xu attr.flags |= PTHREAD_DETACHED; 150*a9b764e2SDavid Xu THR_THREAD_UNLOCK(curthread, pthread); 151*a9b764e2SDavid Xu 152a091d823SDavid Xu memcpy(*dst, &attr, sizeof(struct pthread_attr)); 153a759db94SDavid Xu /* XXX */ 154a759db94SDavid Xu (*dst)->cpuset = NULL; 155a759db94SDavid Xu (*dst)->cpusetsize = 0; 156bb535300SJeff Roberson return (0); 157bb535300SJeff Roberson } 158bb535300SJeff Roberson 159a091d823SDavid Xu __weak_reference(_pthread_attr_getdetachstate, pthread_attr_getdetachstate); 160a091d823SDavid Xu 161bb535300SJeff Roberson int 162bb535300SJeff Roberson _pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate) 163bb535300SJeff Roberson { 164a091d823SDavid Xu int ret; 165bb535300SJeff Roberson 166a091d823SDavid Xu /* Check for invalid arguments: */ 167bb535300SJeff Roberson if (attr == NULL || *attr == NULL || detachstate == NULL) 168a091d823SDavid Xu ret = EINVAL; 169a091d823SDavid Xu else { 170bb535300SJeff Roberson /* Check if the detached flag is set: */ 171bb535300SJeff Roberson if ((*attr)->flags & PTHREAD_DETACHED) 172a091d823SDavid Xu /* Return detached: */ 173bb535300SJeff Roberson *detachstate = PTHREAD_CREATE_DETACHED; 174bb535300SJeff Roberson else 175a091d823SDavid Xu /* Return joinable: */ 176bb535300SJeff Roberson *detachstate = PTHREAD_CREATE_JOINABLE; 177a091d823SDavid Xu ret = 0; 178bb535300SJeff Roberson } 179a091d823SDavid Xu return(ret); 180a091d823SDavid Xu } 181a091d823SDavid Xu 182a091d823SDavid Xu __weak_reference(_pthread_attr_getguardsize, pthread_attr_getguardsize); 183bb535300SJeff Roberson 184bb535300SJeff Roberson int 185bb535300SJeff Roberson _pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize) 186bb535300SJeff Roberson { 187a091d823SDavid Xu int ret; 188a091d823SDavid Xu 189a091d823SDavid Xu /* Check for invalid arguments: */ 190bb535300SJeff Roberson if (attr == NULL || *attr == NULL || guardsize == NULL) 191a091d823SDavid Xu ret = EINVAL; 192a091d823SDavid Xu else { 193a091d823SDavid Xu /* Return the guard size: */ 194bb535300SJeff Roberson *guardsize = (*attr)->guardsize_attr; 195a091d823SDavid Xu ret = 0; 196bb535300SJeff Roberson } 197a091d823SDavid Xu return(ret); 198a091d823SDavid Xu } 199a091d823SDavid Xu 200a091d823SDavid Xu __weak_reference(_pthread_attr_getinheritsched, pthread_attr_getinheritsched); 201bb535300SJeff Roberson 202bb535300SJeff Roberson int 203bb535300SJeff Roberson _pthread_attr_getinheritsched(const pthread_attr_t *attr, int *sched_inherit) 204bb535300SJeff Roberson { 205a091d823SDavid Xu int ret = 0; 206bb535300SJeff Roberson 207a091d823SDavid Xu if ((attr == NULL) || (*attr == NULL)) 208a091d823SDavid Xu ret = EINVAL; 209a091d823SDavid Xu else 210bb535300SJeff Roberson *sched_inherit = (*attr)->sched_inherit; 211bb535300SJeff Roberson 212a091d823SDavid Xu return(ret); 213bb535300SJeff Roberson } 214bb535300SJeff Roberson 215a091d823SDavid Xu __weak_reference(_pthread_attr_getschedparam, pthread_attr_getschedparam); 216a091d823SDavid Xu 217bb535300SJeff Roberson int 218bb535300SJeff Roberson _pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param) 219bb535300SJeff Roberson { 220a091d823SDavid Xu int ret = 0; 221bb535300SJeff Roberson 222a091d823SDavid Xu if ((attr == NULL) || (*attr == NULL) || (param == NULL)) 223a091d823SDavid Xu ret = EINVAL; 224a091d823SDavid Xu else 225bb535300SJeff Roberson param->sched_priority = (*attr)->prio; 226bb535300SJeff Roberson 227a091d823SDavid Xu return(ret); 228bb535300SJeff Roberson } 229bb535300SJeff Roberson 230a091d823SDavid Xu __weak_reference(_pthread_attr_getschedpolicy, pthread_attr_getschedpolicy); 231a091d823SDavid Xu 232bb535300SJeff Roberson int 233bb535300SJeff Roberson _pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy) 234bb535300SJeff Roberson { 235a091d823SDavid Xu int ret = 0; 236bb535300SJeff Roberson 237a091d823SDavid Xu if ((attr == NULL) || (*attr == NULL) || (policy == NULL)) 238a091d823SDavid Xu ret = EINVAL; 239a091d823SDavid Xu else 240bb535300SJeff Roberson *policy = (*attr)->sched_policy; 241bb535300SJeff Roberson 242a091d823SDavid Xu return(ret); 243bb535300SJeff Roberson } 244bb535300SJeff Roberson 245a091d823SDavid Xu __weak_reference(_pthread_attr_getscope, pthread_attr_getscope); 246a091d823SDavid Xu 247bb535300SJeff Roberson int 248bb535300SJeff Roberson _pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope) 249bb535300SJeff Roberson { 250a091d823SDavid Xu int ret = 0; 251bb535300SJeff Roberson 252a091d823SDavid Xu if ((attr == NULL) || (*attr == NULL) || (contentionscope == NULL)) 253a091d823SDavid Xu /* Return an invalid argument: */ 254a091d823SDavid Xu ret = EINVAL; 255a091d823SDavid Xu 256a091d823SDavid Xu else 257bb535300SJeff Roberson *contentionscope = (*attr)->flags & PTHREAD_SCOPE_SYSTEM ? 258bb535300SJeff Roberson PTHREAD_SCOPE_SYSTEM : PTHREAD_SCOPE_PROCESS; 259bb535300SJeff Roberson 260a091d823SDavid Xu return(ret); 261bb535300SJeff Roberson } 262bb535300SJeff Roberson 263a091d823SDavid Xu __weak_reference(_pthread_attr_getstack, pthread_attr_getstack); 264a091d823SDavid Xu 265bb535300SJeff Roberson int 266bb535300SJeff Roberson _pthread_attr_getstack(const pthread_attr_t * __restrict attr, 267bb535300SJeff Roberson void ** __restrict stackaddr, 268bb535300SJeff Roberson size_t * __restrict stacksize) 269bb535300SJeff Roberson { 270a091d823SDavid Xu int ret; 271a091d823SDavid Xu 272a091d823SDavid Xu /* Check for invalid arguments: */ 273bb535300SJeff Roberson if (attr == NULL || *attr == NULL || stackaddr == NULL 274bb535300SJeff Roberson || stacksize == NULL ) 275a091d823SDavid Xu ret = EINVAL; 276a091d823SDavid Xu else { 277a091d823SDavid Xu /* Return the stack address and size */ 278bb535300SJeff Roberson *stackaddr = (*attr)->stackaddr_attr; 279bb535300SJeff Roberson *stacksize = (*attr)->stacksize_attr; 280a091d823SDavid Xu ret = 0; 281bb535300SJeff Roberson } 282a091d823SDavid Xu return(ret); 283a091d823SDavid Xu } 284a091d823SDavid Xu 285a091d823SDavid Xu __weak_reference(_pthread_attr_getstackaddr, pthread_attr_getstackaddr); 286bb535300SJeff Roberson 287bb535300SJeff Roberson int 288bb535300SJeff Roberson _pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr) 289bb535300SJeff Roberson { 290a091d823SDavid Xu int ret; 291a091d823SDavid Xu 292a091d823SDavid Xu /* Check for invalid arguments: */ 293bb535300SJeff Roberson if (attr == NULL || *attr == NULL || stackaddr == NULL) 294a091d823SDavid Xu ret = EINVAL; 295a091d823SDavid Xu else { 296a091d823SDavid Xu /* Return the stack address: */ 297bb535300SJeff Roberson *stackaddr = (*attr)->stackaddr_attr; 298a091d823SDavid Xu ret = 0; 299bb535300SJeff Roberson } 300a091d823SDavid Xu return(ret); 301a091d823SDavid Xu } 302a091d823SDavid Xu 303a091d823SDavid Xu __weak_reference(_pthread_attr_getstacksize, pthread_attr_getstacksize); 304bb535300SJeff Roberson 305bb535300SJeff Roberson int 306bb535300SJeff Roberson _pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize) 307bb535300SJeff Roberson { 308a091d823SDavid Xu int ret; 309a091d823SDavid Xu 310a091d823SDavid Xu /* Check for invalid arguments: */ 311bb535300SJeff Roberson if (attr == NULL || *attr == NULL || stacksize == NULL) 312a091d823SDavid Xu ret = EINVAL; 313a091d823SDavid Xu else { 314a091d823SDavid Xu /* Return the stack size: */ 315bb535300SJeff Roberson *stacksize = (*attr)->stacksize_attr; 316a091d823SDavid Xu ret = 0; 317a091d823SDavid Xu } 318a091d823SDavid Xu return(ret); 319a091d823SDavid Xu } 320bb535300SJeff Roberson 321a091d823SDavid Xu __weak_reference(_pthread_attr_init, pthread_attr_init); 322a091d823SDavid Xu 323a091d823SDavid Xu int 324a091d823SDavid Xu _pthread_attr_init(pthread_attr_t *attr) 325a091d823SDavid Xu { 326a091d823SDavid Xu int ret; 327a091d823SDavid Xu pthread_attr_t pattr; 328a091d823SDavid Xu 329a091d823SDavid Xu _thr_check_init(); 330a091d823SDavid Xu 331a091d823SDavid Xu /* Allocate memory for the attribute object: */ 332a091d823SDavid Xu if ((pattr = (pthread_attr_t) malloc(sizeof(struct pthread_attr))) == NULL) 333a091d823SDavid Xu /* Insufficient memory: */ 334a091d823SDavid Xu ret = ENOMEM; 335a091d823SDavid Xu else { 336a091d823SDavid Xu /* Initialise the attribute object with the defaults: */ 337a091d823SDavid Xu memcpy(pattr, &_pthread_attr_default, sizeof(struct pthread_attr)); 338a091d823SDavid Xu 339a091d823SDavid Xu /* Return a pointer to the attribute object: */ 340a091d823SDavid Xu *attr = pattr; 341a091d823SDavid Xu ret = 0; 342a091d823SDavid Xu } 343a091d823SDavid Xu return(ret); 344a091d823SDavid Xu } 345a091d823SDavid Xu 346a091d823SDavid Xu __weak_reference(_pthread_attr_setcreatesuspend_np, pthread_attr_setcreatesuspend_np); 347a091d823SDavid Xu 348a091d823SDavid Xu int 349a091d823SDavid Xu _pthread_attr_setcreatesuspend_np(pthread_attr_t *attr) 350a091d823SDavid Xu { 351a091d823SDavid Xu int ret; 352a091d823SDavid Xu 353a091d823SDavid Xu if (attr == NULL || *attr == NULL) { 354a091d823SDavid Xu ret = EINVAL; 355a091d823SDavid Xu } else { 356a091d823SDavid Xu (*attr)->suspend = THR_CREATE_SUSPENDED; 357a091d823SDavid Xu ret = 0; 358a091d823SDavid Xu } 359a091d823SDavid Xu return(ret); 360a091d823SDavid Xu } 361a091d823SDavid Xu 362a091d823SDavid Xu __weak_reference(_pthread_attr_setdetachstate, pthread_attr_setdetachstate); 363a091d823SDavid Xu 364a091d823SDavid Xu int 365a091d823SDavid Xu _pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) 366a091d823SDavid Xu { 367a091d823SDavid Xu int ret; 368a091d823SDavid Xu 369a091d823SDavid Xu /* Check for invalid arguments: */ 370a091d823SDavid Xu if (attr == NULL || *attr == NULL || 371a091d823SDavid Xu (detachstate != PTHREAD_CREATE_DETACHED && 372a091d823SDavid Xu detachstate != PTHREAD_CREATE_JOINABLE)) 373a091d823SDavid Xu ret = EINVAL; 374a091d823SDavid Xu else { 375a091d823SDavid Xu /* Check if detached state: */ 376a091d823SDavid Xu if (detachstate == PTHREAD_CREATE_DETACHED) 377a091d823SDavid Xu /* Set the detached flag: */ 378a091d823SDavid Xu (*attr)->flags |= PTHREAD_DETACHED; 379a091d823SDavid Xu else 380a091d823SDavid Xu /* Reset the detached flag: */ 381a091d823SDavid Xu (*attr)->flags &= ~PTHREAD_DETACHED; 382a091d823SDavid Xu ret = 0; 383a091d823SDavid Xu } 384a091d823SDavid Xu return(ret); 385a091d823SDavid Xu } 386a091d823SDavid Xu 387a091d823SDavid Xu __weak_reference(_pthread_attr_setguardsize, pthread_attr_setguardsize); 388a091d823SDavid Xu 389a091d823SDavid Xu int 390a091d823SDavid Xu _pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) 391a091d823SDavid Xu { 392a091d823SDavid Xu int ret; 393a091d823SDavid Xu 394a091d823SDavid Xu /* Check for invalid arguments. */ 395a091d823SDavid Xu if (attr == NULL || *attr == NULL) 396a091d823SDavid Xu ret = EINVAL; 397a091d823SDavid Xu else { 398a091d823SDavid Xu /* Save the stack size. */ 399a091d823SDavid Xu (*attr)->guardsize_attr = guardsize; 400a091d823SDavid Xu ret = 0; 401a091d823SDavid Xu } 402a091d823SDavid Xu return(ret); 403a091d823SDavid Xu } 404a091d823SDavid Xu 405a091d823SDavid Xu __weak_reference(_pthread_attr_setinheritsched, pthread_attr_setinheritsched); 406a091d823SDavid Xu 407a091d823SDavid Xu int 408a091d823SDavid Xu _pthread_attr_setinheritsched(pthread_attr_t *attr, int sched_inherit) 409a091d823SDavid Xu { 410a091d823SDavid Xu int ret = 0; 411a091d823SDavid Xu 412a091d823SDavid Xu if ((attr == NULL) || (*attr == NULL)) 413a091d823SDavid Xu ret = EINVAL; 414a091d823SDavid Xu else if (sched_inherit != PTHREAD_INHERIT_SCHED && 415a091d823SDavid Xu sched_inherit != PTHREAD_EXPLICIT_SCHED) 416a091d823SDavid Xu ret = ENOTSUP; 417a091d823SDavid Xu else 418a091d823SDavid Xu (*attr)->sched_inherit = sched_inherit; 419a091d823SDavid Xu 420a091d823SDavid Xu return(ret); 421a091d823SDavid Xu } 422a091d823SDavid Xu 423a091d823SDavid Xu __weak_reference(_pthread_attr_setschedparam, pthread_attr_setschedparam); 424a091d823SDavid Xu 425a091d823SDavid Xu int 426a091d823SDavid Xu _pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param) 427a091d823SDavid Xu { 428245116caSDavid Xu int policy; 429a091d823SDavid Xu 430a091d823SDavid Xu if ((attr == NULL) || (*attr == NULL)) 431245116caSDavid Xu return (EINVAL); 432245116caSDavid Xu 433245116caSDavid Xu if (param == NULL) 434245116caSDavid Xu return (ENOTSUP); 435245116caSDavid Xu 436245116caSDavid Xu policy = (*attr)->sched_policy; 437245116caSDavid Xu 4387b4f8f03SDavid Xu if (policy == SCHED_FIFO || policy == SCHED_RR) { 439245116caSDavid Xu if (param->sched_priority < _thr_priorities[policy-1].pri_min || 440245116caSDavid Xu param->sched_priority > _thr_priorities[policy-1].pri_max) 441245116caSDavid Xu return (ENOTSUP); 4427b4f8f03SDavid Xu } else { 4437b4f8f03SDavid Xu /* 4447b4f8f03SDavid Xu * Ignore it for SCHED_OTHER now, patches for glib ports 4457b4f8f03SDavid Xu * are wrongly using M:N thread library's internal macro 4467b4f8f03SDavid Xu * THR_MIN_PRIORITY and THR_MAX_PRIORITY. 4477b4f8f03SDavid Xu */ 4487b4f8f03SDavid Xu } 449245116caSDavid Xu 450a091d823SDavid Xu (*attr)->prio = param->sched_priority; 451a091d823SDavid Xu 452245116caSDavid Xu return (0); 453a091d823SDavid Xu } 454a091d823SDavid Xu 455a091d823SDavid Xu __weak_reference(_pthread_attr_setschedpolicy, pthread_attr_setschedpolicy); 456a091d823SDavid Xu 457a091d823SDavid Xu int 458a091d823SDavid Xu _pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy) 459a091d823SDavid Xu { 460a091d823SDavid Xu int ret = 0; 461a091d823SDavid Xu 462a091d823SDavid Xu if ((attr == NULL) || (*attr == NULL)) 463a091d823SDavid Xu ret = EINVAL; 464a091d823SDavid Xu else if ((policy < SCHED_FIFO) || (policy > SCHED_RR)) { 465a091d823SDavid Xu ret = ENOTSUP; 466245116caSDavid Xu } else { 467a091d823SDavid Xu (*attr)->sched_policy = policy; 468245116caSDavid Xu (*attr)->prio = _thr_priorities[policy-1].pri_default; 469245116caSDavid Xu } 470a091d823SDavid Xu return(ret); 471a091d823SDavid Xu } 472a091d823SDavid Xu 473a091d823SDavid Xu __weak_reference(_pthread_attr_setscope, pthread_attr_setscope); 474a091d823SDavid Xu 475a091d823SDavid Xu int 476a091d823SDavid Xu _pthread_attr_setscope(pthread_attr_t *attr, int contentionscope) 477a091d823SDavid Xu { 478a091d823SDavid Xu int ret = 0; 479a091d823SDavid Xu 480a091d823SDavid Xu if ((attr == NULL) || (*attr == NULL)) { 481a091d823SDavid Xu /* Return an invalid argument: */ 482a091d823SDavid Xu ret = EINVAL; 483a091d823SDavid Xu } else if ((contentionscope != PTHREAD_SCOPE_PROCESS) && 484a091d823SDavid Xu (contentionscope != PTHREAD_SCOPE_SYSTEM)) { 485a091d823SDavid Xu ret = EINVAL; 486a091d823SDavid Xu } else if (contentionscope == PTHREAD_SCOPE_SYSTEM) { 487a091d823SDavid Xu (*attr)->flags |= contentionscope; 488a091d823SDavid Xu } else { 489a091d823SDavid Xu (*attr)->flags &= ~PTHREAD_SCOPE_SYSTEM; 490a091d823SDavid Xu } 491a091d823SDavid Xu return (ret); 492a091d823SDavid Xu } 493a091d823SDavid Xu 494a091d823SDavid Xu __weak_reference(_pthread_attr_setstack, pthread_attr_setstack); 495a091d823SDavid Xu 496a091d823SDavid Xu int 497a091d823SDavid Xu _pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, 498a091d823SDavid Xu size_t stacksize) 499a091d823SDavid Xu { 500a091d823SDavid Xu int ret; 501a091d823SDavid Xu 502a091d823SDavid Xu /* Check for invalid arguments: */ 503a091d823SDavid Xu if (attr == NULL || *attr == NULL || stackaddr == NULL 504a091d823SDavid Xu || stacksize < PTHREAD_STACK_MIN) 505a091d823SDavid Xu ret = EINVAL; 506a091d823SDavid Xu else { 507a091d823SDavid Xu /* Save the stack address and stack size */ 508a091d823SDavid Xu (*attr)->stackaddr_attr = stackaddr; 509a091d823SDavid Xu (*attr)->stacksize_attr = stacksize; 510a091d823SDavid Xu ret = 0; 511a091d823SDavid Xu } 512a091d823SDavid Xu return(ret); 513a091d823SDavid Xu } 514a091d823SDavid Xu 515a091d823SDavid Xu __weak_reference(_pthread_attr_setstackaddr, pthread_attr_setstackaddr); 516a091d823SDavid Xu 517a091d823SDavid Xu int 518a091d823SDavid Xu _pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr) 519a091d823SDavid Xu { 520a091d823SDavid Xu int ret; 521a091d823SDavid Xu 522a091d823SDavid Xu /* Check for invalid arguments: */ 523a091d823SDavid Xu if (attr == NULL || *attr == NULL || stackaddr == NULL) 524a091d823SDavid Xu ret = EINVAL; 525a091d823SDavid Xu else { 526a091d823SDavid Xu /* Save the stack address: */ 527a091d823SDavid Xu (*attr)->stackaddr_attr = stackaddr; 528a091d823SDavid Xu ret = 0; 529a091d823SDavid Xu } 530a091d823SDavid Xu return(ret); 531a091d823SDavid Xu } 532a091d823SDavid Xu 533a091d823SDavid Xu __weak_reference(_pthread_attr_setstacksize, pthread_attr_setstacksize); 534a091d823SDavid Xu 535a091d823SDavid Xu int 536a091d823SDavid Xu _pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) 537a091d823SDavid Xu { 538a091d823SDavid Xu int ret; 539a091d823SDavid Xu 540a091d823SDavid Xu /* Check for invalid arguments: */ 541a091d823SDavid Xu if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN) 542a091d823SDavid Xu ret = EINVAL; 543a091d823SDavid Xu else { 544a091d823SDavid Xu /* Save the stack size: */ 545a091d823SDavid Xu (*attr)->stacksize_attr = stacksize; 546a091d823SDavid Xu ret = 0; 547a091d823SDavid Xu } 548a091d823SDavid Xu return(ret); 549bb535300SJeff Roberson } 550a759db94SDavid Xu 551e03efb02SRuslan Ermilov static size_t 552e03efb02SRuslan Ermilov _get_kern_cpuset_size(void) 55321845eb9SDavid Xu { 55421845eb9SDavid Xu static int kern_cpuset_size = 0; 55521845eb9SDavid Xu 55621845eb9SDavid Xu if (kern_cpuset_size == 0) { 557e03efb02SRuslan Ermilov size_t len; 55821845eb9SDavid Xu 55921845eb9SDavid Xu len = sizeof(kern_cpuset_size); 56021845eb9SDavid Xu if (sysctlbyname("kern.smp.maxcpus", &kern_cpuset_size, 56121845eb9SDavid Xu &len, NULL, 0)) 56221845eb9SDavid Xu PANIC("failed to get sysctl kern.smp.maxcpus"); 56321845eb9SDavid Xu 56421845eb9SDavid Xu kern_cpuset_size = (kern_cpuset_size + 7) / 8; 56521845eb9SDavid Xu } 56621845eb9SDavid Xu 56721845eb9SDavid Xu return (kern_cpuset_size); 56821845eb9SDavid Xu } 56921845eb9SDavid Xu 57021845eb9SDavid Xu __weak_reference(_pthread_attr_setaffinity_np, pthread_attr_setaffinity_np); 571a759db94SDavid Xu int 57221845eb9SDavid Xu _pthread_attr_setaffinity_np(pthread_attr_t *pattr, size_t cpusetsize, 573d0aa4fd3SXin LI const cpuset_t *cpusetp) 574a759db94SDavid Xu { 575a759db94SDavid Xu pthread_attr_t attr; 576a759db94SDavid Xu int ret; 577a759db94SDavid Xu 578a759db94SDavid Xu if (pattr == NULL || (attr = (*pattr)) == NULL) 579a759db94SDavid Xu ret = EINVAL; 580a759db94SDavid Xu else { 581d0aa4fd3SXin LI if (cpusetsize == 0 || cpusetp == NULL) { 582a759db94SDavid Xu if (attr->cpuset != NULL) { 583a759db94SDavid Xu free(attr->cpuset); 584a759db94SDavid Xu attr->cpuset = NULL; 585a759db94SDavid Xu attr->cpusetsize = 0; 586a759db94SDavid Xu } 587a759db94SDavid Xu return (0); 588a759db94SDavid Xu } 589a759db94SDavid Xu 59021845eb9SDavid Xu if (cpusetsize > attr->cpusetsize) { 591e03efb02SRuslan Ermilov size_t kern_size = _get_kern_cpuset_size(); 59221845eb9SDavid Xu if (cpusetsize > kern_size) { 593e03efb02SRuslan Ermilov size_t i; 59421845eb9SDavid Xu for (i = kern_size; i < cpusetsize; ++i) { 595d0aa4fd3SXin LI if (((char *)cpusetp)[i]) 59621845eb9SDavid Xu return (EINVAL); 59721845eb9SDavid Xu } 59821845eb9SDavid Xu } 599a759db94SDavid Xu void *newset = realloc(attr->cpuset, cpusetsize); 600a759db94SDavid Xu if (newset == NULL) 601a759db94SDavid Xu return (ENOMEM); 602a759db94SDavid Xu attr->cpuset = newset; 603a759db94SDavid Xu attr->cpusetsize = cpusetsize; 60421845eb9SDavid Xu } else { 60521845eb9SDavid Xu memset(((char *)attr->cpuset) + cpusetsize, 0, 6068a18c0d3SDavid Xu attr->cpusetsize - cpusetsize); 60721845eb9SDavid Xu attr->cpusetsize = cpusetsize; 608a759db94SDavid Xu } 609d0aa4fd3SXin LI memcpy(attr->cpuset, cpusetp, cpusetsize); 610a759db94SDavid Xu ret = 0; 611a759db94SDavid Xu } 612a759db94SDavid Xu return (ret); 613a759db94SDavid Xu } 614a759db94SDavid Xu 61521845eb9SDavid Xu __weak_reference(_pthread_attr_getaffinity_np, pthread_attr_getaffinity_np); 616a759db94SDavid Xu int 61721845eb9SDavid Xu _pthread_attr_getaffinity_np(const pthread_attr_t *pattr, size_t cpusetsize, 618d0aa4fd3SXin LI cpuset_t *cpusetp) 619a759db94SDavid Xu { 620a759db94SDavid Xu pthread_attr_t attr; 621a759db94SDavid Xu int ret = 0; 622a759db94SDavid Xu 623a759db94SDavid Xu if (pattr == NULL || (attr = (*pattr)) == NULL) 624a759db94SDavid Xu ret = EINVAL; 625a759db94SDavid Xu else if (attr->cpuset != NULL) { 626d0aa4fd3SXin LI memcpy(cpusetp, attr->cpuset, MIN(cpusetsize, attr->cpusetsize)); 627a759db94SDavid Xu if (cpusetsize > attr->cpusetsize) 628d0aa4fd3SXin LI memset(((char *)cpusetp) + attr->cpusetsize, 0, 629a759db94SDavid Xu cpusetsize - attr->cpusetsize); 630a759db94SDavid Xu } else { 631e03efb02SRuslan Ermilov size_t kern_size = _get_kern_cpuset_size(); 632d0aa4fd3SXin LI memset(cpusetp, -1, MIN(cpusetsize, kern_size)); 63321845eb9SDavid Xu if (cpusetsize > kern_size) 634d0aa4fd3SXin LI memset(((char *)cpusetp) + kern_size, 0, 63521845eb9SDavid Xu cpusetsize - kern_size); 636a759db94SDavid Xu } 637a759db94SDavid Xu return (ret); 638a759db94SDavid Xu } 639