1df57947fSPedro F. Giffuni /*- 2df57947fSPedro F. Giffuni * SPDX-License-Identifier: BSD-4-Clause 3df57947fSPedro F. Giffuni * 4bb535300SJeff Roberson * Copyright (c) 2003 Craig Rodrigues <rodrigc@attbi.com>. 5bb535300SJeff Roberson * All rights reserved. 6bb535300SJeff Roberson * 7bb535300SJeff Roberson * Redistribution and use in source and binary forms, with or without 8bb535300SJeff Roberson * modification, are permitted provided that the following conditions 9bb535300SJeff Roberson * are met: 10bb535300SJeff Roberson * 1. Redistributions of source code must retain the above copyright 11bb535300SJeff Roberson * notice, this list of conditions and the following disclaimer. 12bb535300SJeff Roberson * 2. Redistributions in binary form must reproduce the above copyright 13bb535300SJeff Roberson * notice, this list of conditions and the following disclaimer in the 14bb535300SJeff Roberson * documentation and/or other materials provided with the distribution. 15bb535300SJeff Roberson * 3. All advertising materials mentioning features or use of this software 16bb535300SJeff Roberson * must display the following acknowledgement: 17bb535300SJeff Roberson * This product includes software developed by Craig Rodrigues. 18bb535300SJeff Roberson * 4. Neither the name of the author nor the names of any co-contributors 19bb535300SJeff Roberson * may be used to endorse or promote products derived from this software 20bb535300SJeff Roberson * without specific prior written permission. 21bb535300SJeff Roberson * 22bb535300SJeff Roberson * THIS SOFTWARE IS PROVIDED BY CRAIG RODRIGUES AND CONTRIBUTORS ``AS IS'' AND 23bb535300SJeff Roberson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24bb535300SJeff Roberson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25bb535300SJeff Roberson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26bb535300SJeff Roberson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27bb535300SJeff Roberson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28bb535300SJeff Roberson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29bb535300SJeff Roberson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30bb535300SJeff Roberson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31bb535300SJeff Roberson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32bb535300SJeff Roberson * SUCH DAMAGE. 33bb535300SJeff Roberson * 34bb535300SJeff Roberson */ 35bb535300SJeff Roberson 36bb535300SJeff Roberson /* 37bb535300SJeff Roberson * Copyright (c) 1998 Daniel Eischen <eischen@vigrid.com>. 38bb535300SJeff Roberson * Copyright (C) 2001 Jason Evans <jasone@freebsd.org>. 39bb535300SJeff Roberson * Copyright (c) 2002,2003 Alexey Zelkin <phantom@FreeBSD.org> 40bb535300SJeff Roberson * All rights reserved. 41bb535300SJeff Roberson * 42bb535300SJeff Roberson * Redistribution and use in source and binary forms, with or without 43bb535300SJeff Roberson * modification, are permitted provided that the following conditions 44bb535300SJeff Roberson * are met: 45bb535300SJeff Roberson * 1. Redistributions of source code must retain the above copyright 46bb535300SJeff Roberson * notice(s), this list of conditions and the following disclaimer 47bb535300SJeff Roberson * unmodified other than the allowable addition of one or more 48bb535300SJeff Roberson * copyright notices. 49bb535300SJeff Roberson * 2. Redistributions in binary form must reproduce the above copyright 50bb535300SJeff Roberson * notice(s), this list of conditions and the following disclaimer in 51bb535300SJeff Roberson * the documentation and/or other materials provided with the 52bb535300SJeff Roberson * distribution. 53bb535300SJeff Roberson * 54bb535300SJeff Roberson * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY 55bb535300SJeff Roberson * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56bb535300SJeff Roberson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 57bb535300SJeff Roberson * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE 58bb535300SJeff Roberson * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 59bb535300SJeff Roberson * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 60bb535300SJeff Roberson * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 61bb535300SJeff Roberson * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 62bb535300SJeff Roberson * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 63bb535300SJeff Roberson * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 64bb535300SJeff Roberson * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 65bb535300SJeff Roberson */ 66bb535300SJeff Roberson 67a091d823SDavid Xu /* 68a091d823SDavid Xu * Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>. 69a091d823SDavid Xu * All rights reserved. 70a091d823SDavid Xu * 71a091d823SDavid Xu * Redistribution and use in source and binary forms, with or without 72a091d823SDavid Xu * modification, are permitted provided that the following conditions 73a091d823SDavid Xu * are met: 74a091d823SDavid Xu * 1. Redistributions of source code must retain the above copyright 75a091d823SDavid Xu * notice, this list of conditions and the following disclaimer. 76a091d823SDavid Xu * 2. Redistributions in binary form must reproduce the above copyright 77a091d823SDavid Xu * notice, this list of conditions and the following disclaimer in the 78a091d823SDavid Xu * documentation and/or other materials provided with the distribution. 79fed32d75SWarner Losh * 3. Neither the name of the author nor the names of any co-contributors 80a091d823SDavid Xu * may be used to endorse or promote products derived from this software 81a091d823SDavid Xu * without specific prior written permission. 82a091d823SDavid Xu * 83a091d823SDavid Xu * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND 84a091d823SDavid Xu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 85a091d823SDavid Xu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 86a091d823SDavid Xu * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 87a091d823SDavid Xu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 88a091d823SDavid Xu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 89a091d823SDavid Xu * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 90a091d823SDavid Xu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 91a091d823SDavid Xu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 92a091d823SDavid Xu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 93a091d823SDavid Xu * SUCH DAMAGE. 94a091d823SDavid Xu */ 95bb535300SJeff Roberson 9632793011SKonstantin Belousov #include <sys/cdefs.h> 9737a6356bSDavid Xu #include "namespace.h" 98bb535300SJeff Roberson #include <errno.h> 99bb535300SJeff Roberson #include <pthread.h> 100bb535300SJeff Roberson #include <stdlib.h> 101bb535300SJeff Roberson #include <string.h> 102a091d823SDavid Xu #include <pthread_np.h> 10321845eb9SDavid Xu #include <sys/sysctl.h> 10437a6356bSDavid Xu #include "un-namespace.h" 105bb535300SJeff Roberson 106bb535300SJeff Roberson #include "thr_private.h" 107bb535300SJeff Roberson 1087f25f6c7SDavid Xu static size_t _get_kern_cpuset_size(void); 1097f25f6c7SDavid Xu 1100ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_destroy, _pthread_attr_destroy); 1110ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_destroy, pthread_attr_destroy); 112bb535300SJeff Roberson 113bb535300SJeff Roberson int 1140ab1bfc7SKonstantin Belousov _thr_attr_destroy(pthread_attr_t *attr) 115bb535300SJeff Roberson { 116bb535300SJeff Roberson 117a091d823SDavid Xu if (attr == NULL || *attr == NULL) 118bd61c1e8SOlivier Certner return (EINVAL); 119bd61c1e8SOlivier Certner 1207f25f6c7SDavid Xu if ((*attr)->cpuset != NULL) 1217f25f6c7SDavid Xu free((*attr)->cpuset); 122bb535300SJeff Roberson free(*attr); 123bb535300SJeff Roberson *attr = NULL; 124bd61c1e8SOlivier Certner return (0); 125bb535300SJeff Roberson } 126bb535300SJeff Roberson 1270ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_get_np, pthread_attr_get_np); 1280ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_get_np, _pthread_attr_get_np); 129bb535300SJeff Roberson 130bb535300SJeff Roberson int 1310ab1bfc7SKonstantin Belousov _thr_attr_get_np(pthread_t pthread, pthread_attr_t *dstattr) 132bb535300SJeff Roberson { 1337f25f6c7SDavid Xu struct pthread_attr attr, *dst; 134bd61c1e8SOlivier Certner struct pthread *curthread; 13567753965SDavid Xu size_t kern_size; 136bd61c1e8SOlivier Certner int error; 137bb535300SJeff Roberson 13865df4577SDavid Xu if (pthread == NULL || dstattr == NULL || (dst = *dstattr) == NULL) 139bb535300SJeff Roberson return (EINVAL); 140bd61c1e8SOlivier Certner 14167753965SDavid Xu kern_size = _get_kern_cpuset_size(); 142bd61c1e8SOlivier Certner 14367753965SDavid Xu if (dst->cpuset == NULL) { 14467753965SDavid Xu dst->cpuset = calloc(1, kern_size); 14567753965SDavid Xu dst->cpusetsize = kern_size; 1467f25f6c7SDavid Xu } 147bd61c1e8SOlivier Certner 148a091d823SDavid Xu curthread = _get_curthread(); 149bd61c1e8SOlivier Certner /* Arg 0 is to include dead threads. */ 150bd61c1e8SOlivier Certner if ((error = _thr_find_thread(curthread, pthread, 0)) != 0) 151bd61c1e8SOlivier Certner return (error); 152bd61c1e8SOlivier Certner 153a9b764e2SDavid Xu attr = pthread->attr; 154a9b764e2SDavid Xu if (pthread->flags & THR_FLAGS_DETACHED) 1554160cda0SDavid Xu attr.flags |= PTHREAD_DETACHED; 156bd61c1e8SOlivier Certner 157bd61c1e8SOlivier Certner error = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, TID(pthread), 1587f25f6c7SDavid Xu dst->cpusetsize, dst->cpuset); 159bd61c1e8SOlivier Certner if (error == -1) 160bd61c1e8SOlivier Certner error = errno; 161bd61c1e8SOlivier Certner 162a9b764e2SDavid Xu THR_THREAD_UNLOCK(curthread, pthread); 163bd61c1e8SOlivier Certner 164bd61c1e8SOlivier Certner if (error == 0) 1657f25f6c7SDavid Xu memcpy(&dst->pthread_attr_start_copy, 1667f25f6c7SDavid Xu &attr.pthread_attr_start_copy, 1677f25f6c7SDavid Xu offsetof(struct pthread_attr, pthread_attr_end_copy) - 1687f25f6c7SDavid Xu offsetof(struct pthread_attr, pthread_attr_start_copy)); 169bd61c1e8SOlivier Certner 170bd61c1e8SOlivier Certner return (0); 171bb535300SJeff Roberson } 172bb535300SJeff Roberson 1730ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getdetachstate, pthread_attr_getdetachstate); 1740ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getdetachstate, _pthread_attr_getdetachstate); 175a091d823SDavid Xu 176bb535300SJeff Roberson int 1770ab1bfc7SKonstantin Belousov _thr_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate) 178bb535300SJeff Roberson { 179bb535300SJeff Roberson 180bb535300SJeff Roberson if (attr == NULL || *attr == NULL || detachstate == NULL) 181bd61c1e8SOlivier Certner return (EINVAL); 182bd61c1e8SOlivier Certner 183bb535300SJeff Roberson if ((*attr)->flags & PTHREAD_DETACHED) 184bb535300SJeff Roberson *detachstate = PTHREAD_CREATE_DETACHED; 185bb535300SJeff Roberson else 186bb535300SJeff Roberson *detachstate = PTHREAD_CREATE_JOINABLE; 187bd61c1e8SOlivier Certner return (0); 188a091d823SDavid Xu } 189a091d823SDavid Xu 1900ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getguardsize, pthread_attr_getguardsize); 1910ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getguardsize, _pthread_attr_getguardsize); 192bb535300SJeff Roberson 193bb535300SJeff Roberson int 1940ab1bfc7SKonstantin Belousov _thr_attr_getguardsize(const pthread_attr_t * __restrict attr, 195b6413b6dSPedro F. Giffuni size_t * __restrict guardsize) 196bb535300SJeff Roberson { 197a091d823SDavid Xu 198bb535300SJeff Roberson if (attr == NULL || *attr == NULL || guardsize == NULL) 199bd61c1e8SOlivier Certner return (EINVAL); 200bd61c1e8SOlivier Certner 201bb535300SJeff Roberson *guardsize = (*attr)->guardsize_attr; 202bd61c1e8SOlivier Certner return (0); 203a091d823SDavid Xu } 204a091d823SDavid Xu 2050ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getinheritsched, pthread_attr_getinheritsched); 2060ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getinheritsched, _pthread_attr_getinheritsched); 207bb535300SJeff Roberson 208bb535300SJeff Roberson int 2090ab1bfc7SKonstantin Belousov _thr_attr_getinheritsched(const pthread_attr_t * __restrict attr, 210b6413b6dSPedro F. Giffuni int * __restrict sched_inherit) 211bb535300SJeff Roberson { 212bb535300SJeff Roberson 213bd61c1e8SOlivier Certner if (attr == NULL || *attr == NULL) 214bd61c1e8SOlivier Certner return (EINVAL); 215bd61c1e8SOlivier Certner 216bb535300SJeff Roberson *sched_inherit = (*attr)->sched_inherit; 217bd61c1e8SOlivier Certner return (0); 218bb535300SJeff Roberson } 219bb535300SJeff Roberson 2200ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getschedparam, pthread_attr_getschedparam); 2210ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getschedparam, _pthread_attr_getschedparam); 222a091d823SDavid Xu 223bb535300SJeff Roberson int 2240ab1bfc7SKonstantin Belousov _thr_attr_getschedparam(const pthread_attr_t * __restrict attr, 225b6413b6dSPedro F. Giffuni struct sched_param * __restrict param) 226bb535300SJeff Roberson { 227bb535300SJeff Roberson 228bd61c1e8SOlivier Certner if (attr == NULL || *attr == NULL || param == NULL) 229bd61c1e8SOlivier Certner return (EINVAL); 230bd61c1e8SOlivier Certner 231bb535300SJeff Roberson param->sched_priority = (*attr)->prio; 232bd61c1e8SOlivier Certner return (0); 233bb535300SJeff Roberson } 234bb535300SJeff Roberson 2350ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getschedpolicy, pthread_attr_getschedpolicy); 2360ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getschedpolicy, _pthread_attr_getschedpolicy); 237a091d823SDavid Xu 238bb535300SJeff Roberson int 2390ab1bfc7SKonstantin Belousov _thr_attr_getschedpolicy(const pthread_attr_t * __restrict attr, 240b6413b6dSPedro F. Giffuni int * __restrict policy) 241bb535300SJeff Roberson { 242bb535300SJeff Roberson 243bd61c1e8SOlivier Certner if (attr == NULL || *attr == NULL || policy == NULL) 244bd61c1e8SOlivier Certner return (EINVAL); 245bd61c1e8SOlivier Certner 246bb535300SJeff Roberson *policy = (*attr)->sched_policy; 247bd61c1e8SOlivier Certner return (0); 248bb535300SJeff Roberson } 249bb535300SJeff Roberson 2500ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getscope, pthread_attr_getscope); 2510ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getscope, _pthread_attr_getscope); 252a091d823SDavid Xu 253bb535300SJeff Roberson int 2540ab1bfc7SKonstantin Belousov _thr_attr_getscope(const pthread_attr_t * __restrict attr, 255b6413b6dSPedro F. Giffuni int * __restrict contentionscope) 256bb535300SJeff Roberson { 257bb535300SJeff Roberson 258bd61c1e8SOlivier Certner if (attr == NULL || *attr == NULL || contentionscope == NULL) 259bd61c1e8SOlivier Certner return (EINVAL); 260a091d823SDavid Xu 261bb535300SJeff Roberson *contentionscope = (*attr)->flags & PTHREAD_SCOPE_SYSTEM ? 262bb535300SJeff Roberson PTHREAD_SCOPE_SYSTEM : PTHREAD_SCOPE_PROCESS; 263bd61c1e8SOlivier Certner return (0); 264bb535300SJeff Roberson } 265bb535300SJeff Roberson 266a091d823SDavid Xu __weak_reference(_pthread_attr_getstack, pthread_attr_getstack); 267a091d823SDavid Xu 268bb535300SJeff Roberson int 269bb535300SJeff Roberson _pthread_attr_getstack(const pthread_attr_t * __restrict attr, 2700ab1bfc7SKonstantin Belousov void ** __restrict stackaddr, size_t * __restrict stacksize) 271bb535300SJeff Roberson { 272a091d823SDavid Xu 273bd61c1e8SOlivier Certner if (attr == NULL || *attr == NULL || stackaddr == NULL || 274bd61c1e8SOlivier Certner stacksize == NULL) 275bd61c1e8SOlivier Certner return (EINVAL); 276bd61c1e8SOlivier Certner 277bb535300SJeff Roberson *stackaddr = (*attr)->stackaddr_attr; 278bb535300SJeff Roberson *stacksize = (*attr)->stacksize_attr; 279bd61c1e8SOlivier Certner return (0); 280a091d823SDavid Xu } 281a091d823SDavid Xu 2820ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getstackaddr, pthread_attr_getstackaddr); 2830ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getstackaddr, _pthread_attr_getstackaddr); 284bb535300SJeff Roberson 285bb535300SJeff Roberson int 2860ab1bfc7SKonstantin Belousov _thr_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr) 287bb535300SJeff Roberson { 288a091d823SDavid Xu 289bb535300SJeff Roberson if (attr == NULL || *attr == NULL || stackaddr == NULL) 290bd61c1e8SOlivier Certner return (EINVAL); 291bd61c1e8SOlivier Certner 292bb535300SJeff Roberson *stackaddr = (*attr)->stackaddr_attr; 293bd61c1e8SOlivier Certner return (0); 294a091d823SDavid Xu } 295a091d823SDavid Xu 2960ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getstacksize, pthread_attr_getstacksize); 2970ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getstacksize, _pthread_attr_getstacksize); 298bb535300SJeff Roberson 299bb535300SJeff Roberson int 3000ab1bfc7SKonstantin Belousov _thr_attr_getstacksize(const pthread_attr_t * __restrict attr, 301b6413b6dSPedro F. Giffuni size_t * __restrict stacksize) 302bb535300SJeff Roberson { 303a091d823SDavid Xu 304bb535300SJeff Roberson if (attr == NULL || *attr == NULL || stacksize == NULL) 305bd61c1e8SOlivier Certner return (EINVAL); 306bd61c1e8SOlivier Certner 307bb535300SJeff Roberson *stacksize = (*attr)->stacksize_attr; 308bd61c1e8SOlivier Certner return (0); 309a091d823SDavid Xu } 310bb535300SJeff Roberson 3110ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_init, pthread_attr_init); 3120ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_init, _pthread_attr_init); 313a091d823SDavid Xu 314a091d823SDavid Xu int 3150ab1bfc7SKonstantin Belousov _thr_attr_init(pthread_attr_t *attr) 316a091d823SDavid Xu { 317a091d823SDavid Xu pthread_attr_t pattr; 318a091d823SDavid Xu 319a091d823SDavid Xu _thr_check_init(); 320a091d823SDavid Xu 321bd61c1e8SOlivier Certner if ((pattr = malloc(sizeof(*pattr))) == NULL) 322bd61c1e8SOlivier Certner return (ENOMEM); 323bd61c1e8SOlivier Certner 324a091d823SDavid Xu memcpy(pattr, &_pthread_attr_default, sizeof(struct pthread_attr)); 325a091d823SDavid Xu *attr = pattr; 326bd61c1e8SOlivier Certner return (0); 327a091d823SDavid Xu } 328a091d823SDavid Xu 329bd61c1e8SOlivier Certner __weak_reference(_pthread_attr_setcreatesuspend_np, \ 330bd61c1e8SOlivier Certner pthread_attr_setcreatesuspend_np); 331a091d823SDavid Xu 332a091d823SDavid Xu int 333a091d823SDavid Xu _pthread_attr_setcreatesuspend_np(pthread_attr_t *attr) 334a091d823SDavid Xu { 335a091d823SDavid Xu 336bd61c1e8SOlivier Certner if (attr == NULL || *attr == NULL) 337bd61c1e8SOlivier Certner return (EINVAL); 338bd61c1e8SOlivier Certner 339a091d823SDavid Xu (*attr)->suspend = THR_CREATE_SUSPENDED; 340bd61c1e8SOlivier Certner return (0); 341a091d823SDavid Xu } 342a091d823SDavid Xu 3430ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setdetachstate, pthread_attr_setdetachstate); 3440ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setdetachstate, _pthread_attr_setdetachstate); 345a091d823SDavid Xu 346a091d823SDavid Xu int 3470ab1bfc7SKonstantin Belousov _thr_attr_setdetachstate(pthread_attr_t *attr, int detachstate) 348a091d823SDavid Xu { 349a091d823SDavid Xu 350a091d823SDavid Xu if (attr == NULL || *attr == NULL || 351a091d823SDavid Xu (detachstate != PTHREAD_CREATE_DETACHED && 352a091d823SDavid Xu detachstate != PTHREAD_CREATE_JOINABLE)) 353bd61c1e8SOlivier Certner return (EINVAL); 354bd61c1e8SOlivier Certner 355a091d823SDavid Xu if (detachstate == PTHREAD_CREATE_DETACHED) 356a091d823SDavid Xu (*attr)->flags |= PTHREAD_DETACHED; 357a091d823SDavid Xu else 358a091d823SDavid Xu (*attr)->flags &= ~PTHREAD_DETACHED; 359bd61c1e8SOlivier Certner return (0); 360a091d823SDavid Xu } 361a091d823SDavid Xu 3620ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setguardsize, pthread_attr_setguardsize); 3630ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setguardsize, _pthread_attr_setguardsize); 364a091d823SDavid Xu 365a091d823SDavid Xu int 3660ab1bfc7SKonstantin Belousov _thr_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) 367a091d823SDavid Xu { 368a091d823SDavid Xu 369a091d823SDavid Xu if (attr == NULL || *attr == NULL) 370bd61c1e8SOlivier Certner return (EINVAL); 371bd61c1e8SOlivier Certner 372a091d823SDavid Xu (*attr)->guardsize_attr = guardsize; 373bd61c1e8SOlivier Certner return (0); 374a091d823SDavid Xu } 375a091d823SDavid Xu 3760ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setinheritsched, pthread_attr_setinheritsched); 3770ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setinheritsched, _pthread_attr_setinheritsched); 378a091d823SDavid Xu 379a091d823SDavid Xu int 3800ab1bfc7SKonstantin Belousov _thr_attr_setinheritsched(pthread_attr_t *attr, int sched_inherit) 381a091d823SDavid Xu { 382a091d823SDavid Xu 383*0eccb459SOlivier Certner if (attr == NULL || *attr == NULL || 384*0eccb459SOlivier Certner (sched_inherit != PTHREAD_INHERIT_SCHED && 385*0eccb459SOlivier Certner sched_inherit != PTHREAD_EXPLICIT_SCHED)) 386bd61c1e8SOlivier Certner return (EINVAL); 387bd61c1e8SOlivier Certner 388bd61c1e8SOlivier Certner (*attr)->sched_inherit = sched_inherit; 389bd61c1e8SOlivier Certner return (0); 390a091d823SDavid Xu } 391a091d823SDavid Xu 3920ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setschedparam, pthread_attr_setschedparam); 3930ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setschedparam, _pthread_attr_setschedparam); 394a091d823SDavid Xu 395a091d823SDavid Xu int 3960ab1bfc7SKonstantin Belousov _thr_attr_setschedparam(pthread_attr_t * __restrict attr, 397b6413b6dSPedro F. Giffuni const struct sched_param * __restrict param) 398a091d823SDavid Xu { 399245116caSDavid Xu int policy; 400a091d823SDavid Xu 401*0eccb459SOlivier Certner if (attr == NULL || *attr == NULL || param == NULL) 402245116caSDavid Xu return (EINVAL); 403245116caSDavid Xu 404245116caSDavid Xu policy = (*attr)->sched_policy; 405245116caSDavid Xu 4067b4f8f03SDavid Xu if (policy == SCHED_FIFO || policy == SCHED_RR) { 407245116caSDavid Xu if (param->sched_priority < _thr_priorities[policy-1].pri_min || 408245116caSDavid Xu param->sched_priority > _thr_priorities[policy-1].pri_max) 409*0eccb459SOlivier Certner return (EINVAL); 4107b4f8f03SDavid Xu } else { 4117b4f8f03SDavid Xu /* 4127b4f8f03SDavid Xu * Ignore it for SCHED_OTHER now, patches for glib ports 4137b4f8f03SDavid Xu * are wrongly using M:N thread library's internal macro 4147b4f8f03SDavid Xu * THR_MIN_PRIORITY and THR_MAX_PRIORITY. 4157b4f8f03SDavid Xu */ 4167b4f8f03SDavid Xu } 417245116caSDavid Xu 418a091d823SDavid Xu (*attr)->prio = param->sched_priority; 419a091d823SDavid Xu 420245116caSDavid Xu return (0); 421a091d823SDavid Xu } 422a091d823SDavid Xu 4230ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setschedpolicy, pthread_attr_setschedpolicy); 4240ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setschedpolicy, _pthread_attr_setschedpolicy); 425a091d823SDavid Xu 426a091d823SDavid Xu int 4270ab1bfc7SKonstantin Belousov _thr_attr_setschedpolicy(pthread_attr_t *attr, int policy) 428a091d823SDavid Xu { 429a091d823SDavid Xu 430*0eccb459SOlivier Certner if (attr == NULL || *attr == NULL || 431*0eccb459SOlivier Certner policy < SCHED_FIFO || policy > SCHED_RR) 432bd61c1e8SOlivier Certner return (EINVAL); 433bd61c1e8SOlivier Certner 434a091d823SDavid Xu (*attr)->sched_policy = policy; 435245116caSDavid Xu (*attr)->prio = _thr_priorities[policy-1].pri_default; 436bd61c1e8SOlivier Certner return (0); 437a091d823SDavid Xu } 438a091d823SDavid Xu 4390ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setscope, pthread_attr_setscope); 4400ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setscope, _pthread_attr_setscope); 441a091d823SDavid Xu 442a091d823SDavid Xu int 4430ab1bfc7SKonstantin Belousov _thr_attr_setscope(pthread_attr_t *attr, int contentionscope) 444a091d823SDavid Xu { 445a091d823SDavid Xu 446bd61c1e8SOlivier Certner if (attr == NULL || *attr == NULL || 447bd61c1e8SOlivier Certner (contentionscope != PTHREAD_SCOPE_PROCESS && 448bd61c1e8SOlivier Certner contentionscope != PTHREAD_SCOPE_SYSTEM)) 449bd61c1e8SOlivier Certner return (EINVAL); 450bd61c1e8SOlivier Certner 451bd61c1e8SOlivier Certner if (contentionscope == PTHREAD_SCOPE_SYSTEM) 452a091d823SDavid Xu (*attr)->flags |= contentionscope; 453bd61c1e8SOlivier Certner else 454a091d823SDavid Xu (*attr)->flags &= ~PTHREAD_SCOPE_SYSTEM; 455bd61c1e8SOlivier Certner return (0); 456a091d823SDavid Xu } 457a091d823SDavid Xu 458a091d823SDavid Xu __weak_reference(_pthread_attr_setstack, pthread_attr_setstack); 459a091d823SDavid Xu 460a091d823SDavid Xu int 461a091d823SDavid Xu _pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, 462a091d823SDavid Xu size_t stacksize) 463a091d823SDavid Xu { 464a091d823SDavid Xu 465bd61c1e8SOlivier Certner if (attr == NULL || *attr == NULL || stackaddr == NULL || 466bd61c1e8SOlivier Certner stacksize < PTHREAD_STACK_MIN) 467bd61c1e8SOlivier Certner return (EINVAL); 468bd61c1e8SOlivier Certner 469a091d823SDavid Xu (*attr)->stackaddr_attr = stackaddr; 470a091d823SDavid Xu (*attr)->stacksize_attr = stacksize; 471bd61c1e8SOlivier Certner return (0); 472a091d823SDavid Xu } 473a091d823SDavid Xu 4740ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setstackaddr, pthread_attr_setstackaddr); 4750ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setstackaddr, _pthread_attr_setstackaddr); 476a091d823SDavid Xu 477a091d823SDavid Xu int 4780ab1bfc7SKonstantin Belousov _thr_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr) 479a091d823SDavid Xu { 480a091d823SDavid Xu 481a091d823SDavid Xu if (attr == NULL || *attr == NULL || stackaddr == NULL) 482bd61c1e8SOlivier Certner return (EINVAL); 483bd61c1e8SOlivier Certner 484a091d823SDavid Xu (*attr)->stackaddr_attr = stackaddr; 485bd61c1e8SOlivier Certner return (0); 486a091d823SDavid Xu } 487a091d823SDavid Xu 4880ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setstacksize, pthread_attr_setstacksize); 4890ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setstacksize, _pthread_attr_setstacksize); 490a091d823SDavid Xu 491a091d823SDavid Xu int 4920ab1bfc7SKonstantin Belousov _thr_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) 493a091d823SDavid Xu { 494a091d823SDavid Xu 495a091d823SDavid Xu if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN) 496bd61c1e8SOlivier Certner return (EINVAL); 497bd61c1e8SOlivier Certner 498a091d823SDavid Xu (*attr)->stacksize_attr = stacksize; 499bd61c1e8SOlivier Certner return (0); 500bb535300SJeff Roberson } 501a759db94SDavid Xu 502e03efb02SRuslan Ermilov static size_t 503e03efb02SRuslan Ermilov _get_kern_cpuset_size(void) 50421845eb9SDavid Xu { 50521845eb9SDavid Xu static int kern_cpuset_size = 0; 50621845eb9SDavid Xu 50721845eb9SDavid Xu if (kern_cpuset_size == 0) { 508e03efb02SRuslan Ermilov size_t len; 50921845eb9SDavid Xu 5101d148640SDavid Xu len = sizeof(kern_cpuset_size); 51101f74ccdSDmitry Chagin if (sysctlbyname("kern.sched.cpusetsizemin", &kern_cpuset_size, 51201f74ccdSDmitry Chagin &len, NULL, 0) != 0 && 51301f74ccdSDmitry Chagin sysctlbyname("kern.sched.cpusetsize", &kern_cpuset_size, 51401f74ccdSDmitry Chagin &len, NULL, 0) != 0) 5151d148640SDavid Xu PANIC("failed to get sysctl kern.sched.cpusetsize"); 51621845eb9SDavid Xu } 51721845eb9SDavid Xu 51821845eb9SDavid Xu return (kern_cpuset_size); 51921845eb9SDavid Xu } 52021845eb9SDavid Xu 52121845eb9SDavid Xu __weak_reference(_pthread_attr_setaffinity_np, pthread_attr_setaffinity_np); 522bd61c1e8SOlivier Certner 523a759db94SDavid Xu int 52421845eb9SDavid Xu _pthread_attr_setaffinity_np(pthread_attr_t *pattr, size_t cpusetsize, 525d0aa4fd3SXin LI const cpuset_t *cpusetp) 526a759db94SDavid Xu { 527a759db94SDavid Xu pthread_attr_t attr; 528bd61c1e8SOlivier Certner size_t kern_size; 529a759db94SDavid Xu 530a759db94SDavid Xu if (pattr == NULL || (attr = (*pattr)) == NULL) 531bd61c1e8SOlivier Certner return (EINVAL); 532bd61c1e8SOlivier Certner 533d0aa4fd3SXin LI if (cpusetsize == 0 || cpusetp == NULL) { 534a759db94SDavid Xu if (attr->cpuset != NULL) { 535a759db94SDavid Xu free(attr->cpuset); 536a759db94SDavid Xu attr->cpuset = NULL; 537a759db94SDavid Xu attr->cpusetsize = 0; 538a759db94SDavid Xu } 539a759db94SDavid Xu return (0); 540a759db94SDavid Xu } 541bd61c1e8SOlivier Certner 542bd61c1e8SOlivier Certner kern_size = _get_kern_cpuset_size(); 54367753965SDavid Xu /* Kernel rejects small set, we check it here too. */ 54467753965SDavid Xu if (cpusetsize < kern_size) 54567753965SDavid Xu return (ERANGE); 54621845eb9SDavid Xu if (cpusetsize > kern_size) { 54767753965SDavid Xu /* Kernel checks invalid bits, we check it here too. */ 548e03efb02SRuslan Ermilov size_t i; 549bd61c1e8SOlivier Certner for (i = kern_size; i < cpusetsize; ++i) 550bd61c1e8SOlivier Certner if (((const char *)cpusetp)[i] != 0) 55121845eb9SDavid Xu return (EINVAL); 55221845eb9SDavid Xu } 55367753965SDavid Xu if (attr->cpuset == NULL) { 55467753965SDavid Xu attr->cpuset = calloc(1, kern_size); 55567753965SDavid Xu if (attr->cpuset == NULL) 55667753965SDavid Xu return (errno); 55767753965SDavid Xu attr->cpusetsize = kern_size; 558a759db94SDavid Xu } 55967753965SDavid Xu memcpy(attr->cpuset, cpusetp, kern_size); 560bd61c1e8SOlivier Certner return (0); 561a759db94SDavid Xu } 562a759db94SDavid Xu 56321845eb9SDavid Xu __weak_reference(_pthread_attr_getaffinity_np, pthread_attr_getaffinity_np); 564bd61c1e8SOlivier Certner 565a759db94SDavid Xu int 56621845eb9SDavid Xu _pthread_attr_getaffinity_np(const pthread_attr_t *pattr, size_t cpusetsize, 567d0aa4fd3SXin LI cpuset_t *cpusetp) 568a759db94SDavid Xu { 569a759db94SDavid Xu pthread_attr_t attr; 570a759db94SDavid Xu 571a759db94SDavid Xu if (pattr == NULL || (attr = (*pattr)) == NULL) 572bd61c1e8SOlivier Certner return (EINVAL); 573bd61c1e8SOlivier Certner 57467753965SDavid Xu /* Kernel rejects small set, we check it here too. */ 575e03efb02SRuslan Ermilov size_t kern_size = _get_kern_cpuset_size(); 57667753965SDavid Xu if (cpusetsize < kern_size) 57767753965SDavid Xu return (ERANGE); 57867753965SDavid Xu if (attr->cpuset != NULL) 57967753965SDavid Xu memcpy(cpusetp, attr->cpuset, MIN(cpusetsize, 58067753965SDavid Xu attr->cpusetsize)); 58167753965SDavid Xu else 58267753965SDavid Xu memset(cpusetp, -1, kern_size); 58321845eb9SDavid Xu if (cpusetsize > kern_size) 584d0aa4fd3SXin LI memset(((char *)cpusetp) + kern_size, 0, 58521845eb9SDavid Xu cpusetsize - kern_size); 586bd61c1e8SOlivier Certner return (0); 587a759db94SDavid Xu } 588