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