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 free((*attr)->cpuset); 121bb535300SJeff Roberson free(*attr); 122bb535300SJeff Roberson *attr = NULL; 123bd61c1e8SOlivier Certner return (0); 124bb535300SJeff Roberson } 125bb535300SJeff Roberson 1260ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_get_np, pthread_attr_get_np); 1270ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_get_np, _pthread_attr_get_np); 128bb535300SJeff Roberson 129bb535300SJeff Roberson int 1300ab1bfc7SKonstantin Belousov _thr_attr_get_np(pthread_t pthread, pthread_attr_t *dstattr) 131bb535300SJeff Roberson { 1327f25f6c7SDavid Xu struct pthread_attr attr, *dst; 133bd61c1e8SOlivier Certner struct pthread *curthread; 13467753965SDavid Xu size_t kern_size; 135bd61c1e8SOlivier Certner int error; 136bb535300SJeff Roberson 13765df4577SDavid Xu if (pthread == NULL || dstattr == NULL || (dst = *dstattr) == NULL) 138bb535300SJeff Roberson return (EINVAL); 139bd61c1e8SOlivier Certner 14067753965SDavid Xu kern_size = _get_kern_cpuset_size(); 141bd61c1e8SOlivier Certner 14267753965SDavid Xu if (dst->cpuset == NULL) { 14367753965SDavid Xu dst->cpuset = calloc(1, kern_size); 14467753965SDavid Xu dst->cpusetsize = kern_size; 1457f25f6c7SDavid Xu } 146bd61c1e8SOlivier Certner 147a091d823SDavid Xu curthread = _get_curthread(); 148bd61c1e8SOlivier Certner /* Arg 0 is to include dead threads. */ 149bd61c1e8SOlivier Certner if ((error = _thr_find_thread(curthread, pthread, 0)) != 0) 150bd61c1e8SOlivier Certner return (error); 151bd61c1e8SOlivier Certner 152a9b764e2SDavid Xu attr = pthread->attr; 153*4d312aa0SOlivier Certner if ((pthread->flags & THR_FLAGS_DETACHED) != 0) 1544160cda0SDavid Xu attr.flags |= PTHREAD_DETACHED; 155bd61c1e8SOlivier Certner 156bd61c1e8SOlivier Certner error = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, TID(pthread), 1577f25f6c7SDavid Xu dst->cpusetsize, dst->cpuset); 158bd61c1e8SOlivier Certner if (error == -1) 159bd61c1e8SOlivier Certner error = errno; 160bd61c1e8SOlivier Certner 161a9b764e2SDavid Xu THR_THREAD_UNLOCK(curthread, pthread); 162bd61c1e8SOlivier Certner 163bd61c1e8SOlivier Certner if (error == 0) 1647f25f6c7SDavid Xu memcpy(&dst->pthread_attr_start_copy, 1657f25f6c7SDavid Xu &attr.pthread_attr_start_copy, 1667f25f6c7SDavid Xu offsetof(struct pthread_attr, pthread_attr_end_copy) - 1677f25f6c7SDavid Xu offsetof(struct pthread_attr, pthread_attr_start_copy)); 168bd61c1e8SOlivier Certner 169bd61c1e8SOlivier Certner return (0); 170bb535300SJeff Roberson } 171bb535300SJeff Roberson 1720ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getdetachstate, pthread_attr_getdetachstate); 1730ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getdetachstate, _pthread_attr_getdetachstate); 174a091d823SDavid Xu 175bb535300SJeff Roberson int 1760ab1bfc7SKonstantin Belousov _thr_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate) 177bb535300SJeff Roberson { 178bb535300SJeff Roberson 179bb535300SJeff Roberson if (attr == NULL || *attr == NULL || detachstate == NULL) 180bd61c1e8SOlivier Certner return (EINVAL); 181bd61c1e8SOlivier Certner 182*4d312aa0SOlivier Certner if (((*attr)->flags & PTHREAD_DETACHED) != 0) 183bb535300SJeff Roberson *detachstate = PTHREAD_CREATE_DETACHED; 184bb535300SJeff Roberson else 185bb535300SJeff Roberson *detachstate = PTHREAD_CREATE_JOINABLE; 186bd61c1e8SOlivier Certner return (0); 187a091d823SDavid Xu } 188a091d823SDavid Xu 1890ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getguardsize, pthread_attr_getguardsize); 1900ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getguardsize, _pthread_attr_getguardsize); 191bb535300SJeff Roberson 192bb535300SJeff Roberson int 1930ab1bfc7SKonstantin Belousov _thr_attr_getguardsize(const pthread_attr_t * __restrict attr, 194b6413b6dSPedro F. Giffuni size_t * __restrict guardsize) 195bb535300SJeff Roberson { 196a091d823SDavid Xu 197bb535300SJeff Roberson if (attr == NULL || *attr == NULL || guardsize == NULL) 198bd61c1e8SOlivier Certner return (EINVAL); 199bd61c1e8SOlivier Certner 200bb535300SJeff Roberson *guardsize = (*attr)->guardsize_attr; 201bd61c1e8SOlivier Certner return (0); 202a091d823SDavid Xu } 203a091d823SDavid Xu 2040ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getinheritsched, pthread_attr_getinheritsched); 2050ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getinheritsched, _pthread_attr_getinheritsched); 206bb535300SJeff Roberson 207bb535300SJeff Roberson int 2080ab1bfc7SKonstantin Belousov _thr_attr_getinheritsched(const pthread_attr_t * __restrict attr, 209b6413b6dSPedro F. Giffuni int * __restrict sched_inherit) 210bb535300SJeff Roberson { 211bb535300SJeff Roberson 212bd61c1e8SOlivier Certner if (attr == NULL || *attr == NULL) 213bd61c1e8SOlivier Certner return (EINVAL); 214bd61c1e8SOlivier Certner 215bb535300SJeff Roberson *sched_inherit = (*attr)->sched_inherit; 216bd61c1e8SOlivier Certner return (0); 217bb535300SJeff Roberson } 218bb535300SJeff Roberson 2190ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getschedparam, pthread_attr_getschedparam); 2200ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getschedparam, _pthread_attr_getschedparam); 221a091d823SDavid Xu 222bb535300SJeff Roberson int 2230ab1bfc7SKonstantin Belousov _thr_attr_getschedparam(const pthread_attr_t * __restrict attr, 224b6413b6dSPedro F. Giffuni struct sched_param * __restrict param) 225bb535300SJeff Roberson { 226bb535300SJeff Roberson 227bd61c1e8SOlivier Certner if (attr == NULL || *attr == NULL || param == NULL) 228bd61c1e8SOlivier Certner return (EINVAL); 229bd61c1e8SOlivier Certner 230bb535300SJeff Roberson param->sched_priority = (*attr)->prio; 231bd61c1e8SOlivier Certner return (0); 232bb535300SJeff Roberson } 233bb535300SJeff Roberson 2340ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getschedpolicy, pthread_attr_getschedpolicy); 2350ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getschedpolicy, _pthread_attr_getschedpolicy); 236a091d823SDavid Xu 237bb535300SJeff Roberson int 2380ab1bfc7SKonstantin Belousov _thr_attr_getschedpolicy(const pthread_attr_t * __restrict attr, 239b6413b6dSPedro F. Giffuni int * __restrict policy) 240bb535300SJeff Roberson { 241bb535300SJeff Roberson 242bd61c1e8SOlivier Certner if (attr == NULL || *attr == NULL || policy == NULL) 243bd61c1e8SOlivier Certner return (EINVAL); 244bd61c1e8SOlivier Certner 245bb535300SJeff Roberson *policy = (*attr)->sched_policy; 246bd61c1e8SOlivier Certner return (0); 247bb535300SJeff Roberson } 248bb535300SJeff Roberson 2490ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getscope, pthread_attr_getscope); 2500ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getscope, _pthread_attr_getscope); 251a091d823SDavid Xu 252bb535300SJeff Roberson int 2530ab1bfc7SKonstantin Belousov _thr_attr_getscope(const pthread_attr_t * __restrict attr, 254b6413b6dSPedro F. Giffuni int * __restrict contentionscope) 255bb535300SJeff Roberson { 256bb535300SJeff Roberson 257bd61c1e8SOlivier Certner if (attr == NULL || *attr == NULL || contentionscope == NULL) 258bd61c1e8SOlivier Certner return (EINVAL); 259a091d823SDavid Xu 260*4d312aa0SOlivier Certner *contentionscope = ((*attr)->flags & PTHREAD_SCOPE_SYSTEM) != 0 ? 261bb535300SJeff Roberson PTHREAD_SCOPE_SYSTEM : PTHREAD_SCOPE_PROCESS; 262bd61c1e8SOlivier Certner return (0); 263bb535300SJeff Roberson } 264bb535300SJeff Roberson 265a091d823SDavid Xu __weak_reference(_pthread_attr_getstack, pthread_attr_getstack); 266a091d823SDavid Xu 267bb535300SJeff Roberson int 268bb535300SJeff Roberson _pthread_attr_getstack(const pthread_attr_t * __restrict attr, 2690ab1bfc7SKonstantin Belousov void ** __restrict stackaddr, size_t * __restrict stacksize) 270bb535300SJeff Roberson { 271a091d823SDavid Xu 272bd61c1e8SOlivier Certner if (attr == NULL || *attr == NULL || stackaddr == NULL || 273bd61c1e8SOlivier Certner stacksize == NULL) 274bd61c1e8SOlivier Certner return (EINVAL); 275bd61c1e8SOlivier Certner 276bb535300SJeff Roberson *stackaddr = (*attr)->stackaddr_attr; 277bb535300SJeff Roberson *stacksize = (*attr)->stacksize_attr; 278bd61c1e8SOlivier Certner return (0); 279a091d823SDavid Xu } 280a091d823SDavid Xu 2810ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getstackaddr, pthread_attr_getstackaddr); 2820ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getstackaddr, _pthread_attr_getstackaddr); 283bb535300SJeff Roberson 284bb535300SJeff Roberson int 2850ab1bfc7SKonstantin Belousov _thr_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr) 286bb535300SJeff Roberson { 287a091d823SDavid Xu 288bb535300SJeff Roberson if (attr == NULL || *attr == NULL || stackaddr == NULL) 289bd61c1e8SOlivier Certner return (EINVAL); 290bd61c1e8SOlivier Certner 291bb535300SJeff Roberson *stackaddr = (*attr)->stackaddr_attr; 292bd61c1e8SOlivier Certner return (0); 293a091d823SDavid Xu } 294a091d823SDavid Xu 2950ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getstacksize, pthread_attr_getstacksize); 2960ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_getstacksize, _pthread_attr_getstacksize); 297bb535300SJeff Roberson 298bb535300SJeff Roberson int 2990ab1bfc7SKonstantin Belousov _thr_attr_getstacksize(const pthread_attr_t * __restrict attr, 300b6413b6dSPedro F. Giffuni size_t * __restrict stacksize) 301bb535300SJeff Roberson { 302a091d823SDavid Xu 303bb535300SJeff Roberson if (attr == NULL || *attr == NULL || stacksize == NULL) 304bd61c1e8SOlivier Certner return (EINVAL); 305bd61c1e8SOlivier Certner 306bb535300SJeff Roberson *stacksize = (*attr)->stacksize_attr; 307bd61c1e8SOlivier Certner return (0); 308a091d823SDavid Xu } 309bb535300SJeff Roberson 3100ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_init, pthread_attr_init); 3110ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_init, _pthread_attr_init); 312a091d823SDavid Xu 313a091d823SDavid Xu int 3140ab1bfc7SKonstantin Belousov _thr_attr_init(pthread_attr_t *attr) 315a091d823SDavid Xu { 316a091d823SDavid Xu pthread_attr_t pattr; 317a091d823SDavid Xu 318a091d823SDavid Xu _thr_check_init(); 319a091d823SDavid Xu 320bd61c1e8SOlivier Certner if ((pattr = malloc(sizeof(*pattr))) == NULL) 321bd61c1e8SOlivier Certner return (ENOMEM); 322bd61c1e8SOlivier Certner 323*4d312aa0SOlivier Certner memcpy(pattr, &_pthread_attr_default, sizeof(*pattr)); 324a091d823SDavid Xu *attr = pattr; 325bd61c1e8SOlivier Certner return (0); 326a091d823SDavid Xu } 327a091d823SDavid Xu 328bd61c1e8SOlivier Certner __weak_reference(_pthread_attr_setcreatesuspend_np, \ 329bd61c1e8SOlivier Certner pthread_attr_setcreatesuspend_np); 330a091d823SDavid Xu 331a091d823SDavid Xu int 332a091d823SDavid Xu _pthread_attr_setcreatesuspend_np(pthread_attr_t *attr) 333a091d823SDavid Xu { 334a091d823SDavid Xu 335bd61c1e8SOlivier Certner if (attr == NULL || *attr == NULL) 336bd61c1e8SOlivier Certner return (EINVAL); 337bd61c1e8SOlivier Certner 338a091d823SDavid Xu (*attr)->suspend = THR_CREATE_SUSPENDED; 339bd61c1e8SOlivier Certner return (0); 340a091d823SDavid Xu } 341a091d823SDavid Xu 3420ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setdetachstate, pthread_attr_setdetachstate); 3430ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setdetachstate, _pthread_attr_setdetachstate); 344a091d823SDavid Xu 345a091d823SDavid Xu int 3460ab1bfc7SKonstantin Belousov _thr_attr_setdetachstate(pthread_attr_t *attr, int detachstate) 347a091d823SDavid Xu { 348a091d823SDavid Xu 349a091d823SDavid Xu if (attr == NULL || *attr == NULL || 350a091d823SDavid Xu (detachstate != PTHREAD_CREATE_DETACHED && 351a091d823SDavid Xu detachstate != PTHREAD_CREATE_JOINABLE)) 352bd61c1e8SOlivier Certner return (EINVAL); 353bd61c1e8SOlivier Certner 354a091d823SDavid Xu if (detachstate == PTHREAD_CREATE_DETACHED) 355a091d823SDavid Xu (*attr)->flags |= PTHREAD_DETACHED; 356a091d823SDavid Xu else 357a091d823SDavid Xu (*attr)->flags &= ~PTHREAD_DETACHED; 358bd61c1e8SOlivier Certner return (0); 359a091d823SDavid Xu } 360a091d823SDavid Xu 3610ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setguardsize, pthread_attr_setguardsize); 3620ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setguardsize, _pthread_attr_setguardsize); 363a091d823SDavid Xu 364a091d823SDavid Xu int 3650ab1bfc7SKonstantin Belousov _thr_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) 366a091d823SDavid Xu { 367a091d823SDavid Xu 368a091d823SDavid Xu if (attr == NULL || *attr == NULL) 369bd61c1e8SOlivier Certner return (EINVAL); 370bd61c1e8SOlivier Certner 371a091d823SDavid Xu (*attr)->guardsize_attr = guardsize; 372bd61c1e8SOlivier Certner return (0); 373a091d823SDavid Xu } 374a091d823SDavid Xu 3750ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setinheritsched, pthread_attr_setinheritsched); 3760ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setinheritsched, _pthread_attr_setinheritsched); 377a091d823SDavid Xu 378a091d823SDavid Xu int 3790ab1bfc7SKonstantin Belousov _thr_attr_setinheritsched(pthread_attr_t *attr, int sched_inherit) 380a091d823SDavid Xu { 381a091d823SDavid Xu 3820eccb459SOlivier Certner if (attr == NULL || *attr == NULL || 3830eccb459SOlivier Certner (sched_inherit != PTHREAD_INHERIT_SCHED && 3840eccb459SOlivier Certner sched_inherit != PTHREAD_EXPLICIT_SCHED)) 385bd61c1e8SOlivier Certner return (EINVAL); 386bd61c1e8SOlivier Certner 387bd61c1e8SOlivier Certner (*attr)->sched_inherit = sched_inherit; 388bd61c1e8SOlivier Certner return (0); 389a091d823SDavid Xu } 390a091d823SDavid Xu 3910ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setschedparam, pthread_attr_setschedparam); 3920ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setschedparam, _pthread_attr_setschedparam); 393a091d823SDavid Xu 394a091d823SDavid Xu int 3950ab1bfc7SKonstantin Belousov _thr_attr_setschedparam(pthread_attr_t * __restrict attr, 396b6413b6dSPedro F. Giffuni const struct sched_param * __restrict param) 397a091d823SDavid Xu { 398245116caSDavid Xu int policy; 399a091d823SDavid Xu 4000eccb459SOlivier Certner if (attr == NULL || *attr == NULL || param == NULL) 401245116caSDavid Xu return (EINVAL); 402245116caSDavid Xu 403245116caSDavid Xu policy = (*attr)->sched_policy; 404245116caSDavid Xu 4057b4f8f03SDavid Xu if (policy == SCHED_FIFO || policy == SCHED_RR) { 406245116caSDavid Xu if (param->sched_priority < _thr_priorities[policy-1].pri_min || 407245116caSDavid Xu param->sched_priority > _thr_priorities[policy-1].pri_max) 4080eccb459SOlivier Certner return (EINVAL); 4097b4f8f03SDavid Xu } else { 4107b4f8f03SDavid Xu /* 4117b4f8f03SDavid Xu * Ignore it for SCHED_OTHER now, patches for glib ports 4127b4f8f03SDavid Xu * are wrongly using M:N thread library's internal macro 4137b4f8f03SDavid Xu * THR_MIN_PRIORITY and THR_MAX_PRIORITY. 4147b4f8f03SDavid Xu */ 4157b4f8f03SDavid Xu } 416245116caSDavid Xu 417a091d823SDavid Xu (*attr)->prio = param->sched_priority; 418a091d823SDavid Xu 419245116caSDavid Xu return (0); 420a091d823SDavid Xu } 421a091d823SDavid Xu 4220ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setschedpolicy, pthread_attr_setschedpolicy); 4230ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setschedpolicy, _pthread_attr_setschedpolicy); 424a091d823SDavid Xu 425a091d823SDavid Xu int 4260ab1bfc7SKonstantin Belousov _thr_attr_setschedpolicy(pthread_attr_t *attr, int policy) 427a091d823SDavid Xu { 428a091d823SDavid Xu 4290eccb459SOlivier Certner if (attr == NULL || *attr == NULL || 4300eccb459SOlivier Certner policy < SCHED_FIFO || policy > SCHED_RR) 431bd61c1e8SOlivier Certner return (EINVAL); 432bd61c1e8SOlivier Certner 433a091d823SDavid Xu (*attr)->sched_policy = policy; 434245116caSDavid Xu (*attr)->prio = _thr_priorities[policy-1].pri_default; 435bd61c1e8SOlivier Certner return (0); 436a091d823SDavid Xu } 437a091d823SDavid Xu 4380ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setscope, pthread_attr_setscope); 4390ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setscope, _pthread_attr_setscope); 440a091d823SDavid Xu 441a091d823SDavid Xu int 4420ab1bfc7SKonstantin Belousov _thr_attr_setscope(pthread_attr_t *attr, int contentionscope) 443a091d823SDavid Xu { 444a091d823SDavid Xu 445bd61c1e8SOlivier Certner if (attr == NULL || *attr == NULL || 446bd61c1e8SOlivier Certner (contentionscope != PTHREAD_SCOPE_PROCESS && 447bd61c1e8SOlivier Certner contentionscope != PTHREAD_SCOPE_SYSTEM)) 448bd61c1e8SOlivier Certner return (EINVAL); 449bd61c1e8SOlivier Certner 450bd61c1e8SOlivier Certner if (contentionscope == PTHREAD_SCOPE_SYSTEM) 451*4d312aa0SOlivier Certner (*attr)->flags |= PTHREAD_SCOPE_SYSTEM; 452bd61c1e8SOlivier Certner else 453a091d823SDavid Xu (*attr)->flags &= ~PTHREAD_SCOPE_SYSTEM; 454bd61c1e8SOlivier Certner return (0); 455a091d823SDavid Xu } 456a091d823SDavid Xu 457a091d823SDavid Xu __weak_reference(_pthread_attr_setstack, pthread_attr_setstack); 458a091d823SDavid Xu 459a091d823SDavid Xu int 460a091d823SDavid Xu _pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, 461a091d823SDavid Xu size_t stacksize) 462a091d823SDavid Xu { 463a091d823SDavid Xu 464bd61c1e8SOlivier Certner if (attr == NULL || *attr == NULL || stackaddr == NULL || 465bd61c1e8SOlivier Certner stacksize < PTHREAD_STACK_MIN) 466bd61c1e8SOlivier Certner return (EINVAL); 467bd61c1e8SOlivier Certner 468a091d823SDavid Xu (*attr)->stackaddr_attr = stackaddr; 469a091d823SDavid Xu (*attr)->stacksize_attr = stacksize; 470bd61c1e8SOlivier Certner return (0); 471a091d823SDavid Xu } 472a091d823SDavid Xu 4730ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setstackaddr, pthread_attr_setstackaddr); 4740ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setstackaddr, _pthread_attr_setstackaddr); 475a091d823SDavid Xu 476a091d823SDavid Xu int 4770ab1bfc7SKonstantin Belousov _thr_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr) 478a091d823SDavid Xu { 479a091d823SDavid Xu 480a091d823SDavid Xu if (attr == NULL || *attr == NULL || stackaddr == NULL) 481bd61c1e8SOlivier Certner return (EINVAL); 482bd61c1e8SOlivier Certner 483a091d823SDavid Xu (*attr)->stackaddr_attr = stackaddr; 484bd61c1e8SOlivier Certner return (0); 485a091d823SDavid Xu } 486a091d823SDavid Xu 4870ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setstacksize, pthread_attr_setstacksize); 4880ab1bfc7SKonstantin Belousov __weak_reference(_thr_attr_setstacksize, _pthread_attr_setstacksize); 489a091d823SDavid Xu 490a091d823SDavid Xu int 4910ab1bfc7SKonstantin Belousov _thr_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) 492a091d823SDavid Xu { 493a091d823SDavid Xu 494a091d823SDavid Xu if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN) 495bd61c1e8SOlivier Certner return (EINVAL); 496bd61c1e8SOlivier Certner 497a091d823SDavid Xu (*attr)->stacksize_attr = stacksize; 498bd61c1e8SOlivier Certner return (0); 499bb535300SJeff Roberson } 500a759db94SDavid Xu 501e03efb02SRuslan Ermilov static size_t 502e03efb02SRuslan Ermilov _get_kern_cpuset_size(void) 50321845eb9SDavid Xu { 50421845eb9SDavid Xu static int kern_cpuset_size = 0; 50521845eb9SDavid Xu 50621845eb9SDavid Xu if (kern_cpuset_size == 0) { 507e03efb02SRuslan Ermilov size_t len; 50821845eb9SDavid Xu 5091d148640SDavid Xu len = sizeof(kern_cpuset_size); 51001f74ccdSDmitry Chagin if (sysctlbyname("kern.sched.cpusetsizemin", &kern_cpuset_size, 51101f74ccdSDmitry Chagin &len, NULL, 0) != 0 && 51201f74ccdSDmitry Chagin sysctlbyname("kern.sched.cpusetsize", &kern_cpuset_size, 51301f74ccdSDmitry Chagin &len, NULL, 0) != 0) 5141d148640SDavid Xu PANIC("failed to get sysctl kern.sched.cpusetsize"); 51521845eb9SDavid Xu } 51621845eb9SDavid Xu 51721845eb9SDavid Xu return (kern_cpuset_size); 51821845eb9SDavid Xu } 51921845eb9SDavid Xu 52021845eb9SDavid Xu __weak_reference(_pthread_attr_setaffinity_np, pthread_attr_setaffinity_np); 521bd61c1e8SOlivier Certner 522a759db94SDavid Xu int 52321845eb9SDavid Xu _pthread_attr_setaffinity_np(pthread_attr_t *pattr, size_t cpusetsize, 524d0aa4fd3SXin LI const cpuset_t *cpusetp) 525a759db94SDavid Xu { 526a759db94SDavid Xu pthread_attr_t attr; 527bd61c1e8SOlivier Certner size_t kern_size; 528a759db94SDavid Xu 529a759db94SDavid Xu if (pattr == NULL || (attr = (*pattr)) == NULL) 530bd61c1e8SOlivier Certner return (EINVAL); 531bd61c1e8SOlivier Certner 532d0aa4fd3SXin LI if (cpusetsize == 0 || cpusetp == NULL) { 533a759db94SDavid Xu if (attr->cpuset != NULL) { 534a759db94SDavid Xu free(attr->cpuset); 535a759db94SDavid Xu attr->cpuset = NULL; 536a759db94SDavid Xu attr->cpusetsize = 0; 537a759db94SDavid Xu } 538a759db94SDavid Xu return (0); 539a759db94SDavid Xu } 540bd61c1e8SOlivier Certner 541bd61c1e8SOlivier Certner kern_size = _get_kern_cpuset_size(); 54267753965SDavid Xu /* Kernel rejects small set, we check it here too. */ 54367753965SDavid Xu if (cpusetsize < kern_size) 54467753965SDavid Xu return (ERANGE); 54521845eb9SDavid Xu if (cpusetsize > kern_size) { 54667753965SDavid Xu /* Kernel checks invalid bits, we check it here too. */ 547e03efb02SRuslan Ermilov size_t i; 548*4d312aa0SOlivier Certner 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