1 1.21 riastrad /* $NetBSD: pthread_attr.c,v 1.21 2022/04/10 10:38:33 riastradh Exp $ */ 2 1.1 nathanw 3 1.1 nathanw /*- 4 1.10 ad * Copyright (c) 2001, 2002, 2003, 2008 The NetBSD Foundation, Inc. 5 1.1 nathanw * All rights reserved. 6 1.1 nathanw * 7 1.1 nathanw * This code is derived from software contributed to The NetBSD Foundation 8 1.1 nathanw * by Nathan J. Williams. 9 1.1 nathanw * 10 1.1 nathanw * Redistribution and use in source and binary forms, with or without 11 1.1 nathanw * modification, are permitted provided that the following conditions 12 1.1 nathanw * are met: 13 1.1 nathanw * 1. Redistributions of source code must retain the above copyright 14 1.1 nathanw * notice, this list of conditions and the following disclaimer. 15 1.1 nathanw * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 nathanw * notice, this list of conditions and the following disclaimer in the 17 1.1 nathanw * documentation and/or other materials provided with the distribution. 18 1.1 nathanw * 19 1.1 nathanw * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 nathanw * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 nathanw * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 nathanw * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 nathanw * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 nathanw * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 nathanw * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 nathanw * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 nathanw * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 nathanw * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 nathanw * POSSIBILITY OF SUCH DAMAGE. 30 1.1 nathanw */ 31 1.1 nathanw 32 1.1 nathanw #include <sys/cdefs.h> 33 1.21 riastrad __RCSID("$NetBSD: pthread_attr.c,v 1.21 2022/04/10 10:38:33 riastradh Exp $"); 34 1.20 riastrad 35 1.20 riastrad /* Need to use libc-private names for atomic operations. */ 36 1.20 riastrad #include "../../common/lib/libc/atomic/atomic_op_namespace.h" 37 1.1 nathanw 38 1.1 nathanw #include <errno.h> 39 1.1 nathanw #include <stdio.h> 40 1.1 nathanw #include <stdlib.h> 41 1.1 nathanw #include <string.h> 42 1.1 nathanw #include <unistd.h> 43 1.1 nathanw 44 1.14 christos #ifndef __lint__ 45 1.14 christos #define pthread_attr_get_np _pthread_attr_get_np 46 1.14 christos #endif 47 1.14 christos 48 1.15 christos #include "pthread.h" 49 1.15 christos #include "pthread_int.h" 50 1.15 christos 51 1.14 christos __weak_alias(pthread_attr_get_np, _pthread_attr_get_np) 52 1.14 christos 53 1.7 christos static struct pthread_attr_private *pthread__attr_init_private( 54 1.7 christos pthread_attr_t *); 55 1.1 nathanw 56 1.1 nathanw static struct pthread_attr_private * 57 1.1 nathanw pthread__attr_init_private(pthread_attr_t *attr) 58 1.1 nathanw { 59 1.1 nathanw struct pthread_attr_private *p; 60 1.1 nathanw 61 1.1 nathanw if ((p = attr->pta_private) != NULL) 62 1.1 nathanw return p; 63 1.1 nathanw 64 1.18 martin p = calloc(1, sizeof(*p)); 65 1.1 nathanw if (p != NULL) { 66 1.1 nathanw attr->pta_private = p; 67 1.10 ad p->ptap_policy = SCHED_OTHER; 68 1.18 martin p->ptap_stacksize = pthread__stacksize; 69 1.18 martin p->ptap_guardsize = pthread__guardsize; 70 1.1 nathanw } 71 1.1 nathanw return p; 72 1.1 nathanw } 73 1.1 nathanw 74 1.1 nathanw 75 1.1 nathanw int 76 1.1 nathanw pthread_attr_init(pthread_attr_t *attr) 77 1.1 nathanw { 78 1.1 nathanw 79 1.1 nathanw attr->pta_magic = PT_ATTR_MAGIC; 80 1.1 nathanw attr->pta_flags = 0; 81 1.1 nathanw attr->pta_private = NULL; 82 1.1 nathanw 83 1.1 nathanw return 0; 84 1.1 nathanw } 85 1.1 nathanw 86 1.1 nathanw 87 1.1 nathanw int 88 1.1 nathanw pthread_attr_destroy(pthread_attr_t *attr) 89 1.1 nathanw { 90 1.1 nathanw struct pthread_attr_private *p; 91 1.1 nathanw 92 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 93 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 94 1.19 kamil 95 1.1 nathanw if ((p = attr->pta_private) != NULL) 96 1.1 nathanw free(p); 97 1.1 nathanw 98 1.19 kamil attr->pta_magic = PT_ATTR_DEAD; 99 1.19 kamil 100 1.1 nathanw return 0; 101 1.1 nathanw } 102 1.1 nathanw 103 1.1 nathanw 104 1.1 nathanw int 105 1.1 nathanw pthread_attr_get_np(pthread_t thread, pthread_attr_t *attr) 106 1.1 nathanw { 107 1.1 nathanw struct pthread_attr_private *p; 108 1.1 nathanw 109 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 110 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 111 1.19 kamil 112 1.1 nathanw p = pthread__attr_init_private(attr); 113 1.1 nathanw if (p == NULL) 114 1.1 nathanw return ENOMEM; 115 1.1 nathanw 116 1.21 riastrad attr->pta_flags = thread->pt_flags & 117 1.1 nathanw (PT_FLAG_DETACHED | PT_FLAG_SCOPE_SYSTEM | PT_FLAG_EXPLICIT_SCHED); 118 1.1 nathanw 119 1.1 nathanw p->ptap_namearg = thread->pt_name; 120 1.1 nathanw p->ptap_stackaddr = thread->pt_stack.ss_sp; 121 1.1 nathanw p->ptap_stacksize = thread->pt_stack.ss_size; 122 1.17 joerg p->ptap_guardsize = thread->pt_guardsize; 123 1.10 ad return pthread_getschedparam(thread, &p->ptap_policy, &p->ptap_sp); 124 1.1 nathanw } 125 1.1 nathanw 126 1.1 nathanw 127 1.1 nathanw int 128 1.1 nathanw pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate) 129 1.1 nathanw { 130 1.1 nathanw 131 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 132 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 133 1.19 kamil 134 1.1 nathanw if (attr->pta_flags & PT_FLAG_DETACHED) 135 1.1 nathanw *detachstate = PTHREAD_CREATE_DETACHED; 136 1.1 nathanw else 137 1.1 nathanw *detachstate = PTHREAD_CREATE_JOINABLE; 138 1.1 nathanw 139 1.1 nathanw return 0; 140 1.1 nathanw } 141 1.1 nathanw 142 1.1 nathanw 143 1.1 nathanw int 144 1.1 nathanw pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) 145 1.1 nathanw { 146 1.1 nathanw 147 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 148 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 149 1.19 kamil 150 1.1 nathanw switch (detachstate) { 151 1.1 nathanw case PTHREAD_CREATE_JOINABLE: 152 1.1 nathanw attr->pta_flags &= ~PT_FLAG_DETACHED; 153 1.1 nathanw break; 154 1.1 nathanw case PTHREAD_CREATE_DETACHED: 155 1.1 nathanw attr->pta_flags |= PT_FLAG_DETACHED; 156 1.1 nathanw break; 157 1.1 nathanw default: 158 1.1 nathanw return EINVAL; 159 1.1 nathanw } 160 1.1 nathanw 161 1.1 nathanw return 0; 162 1.1 nathanw } 163 1.1 nathanw 164 1.1 nathanw 165 1.1 nathanw int 166 1.1 nathanw pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guard) 167 1.1 nathanw { 168 1.1 nathanw struct pthread_attr_private *p; 169 1.1 nathanw 170 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 171 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 172 1.19 kamil 173 1.1 nathanw if ((p = attr->pta_private) == NULL) 174 1.17 joerg *guard = pthread__guardsize; 175 1.1 nathanw else 176 1.1 nathanw *guard = p->ptap_guardsize; 177 1.1 nathanw 178 1.1 nathanw return 0; 179 1.1 nathanw } 180 1.1 nathanw 181 1.1 nathanw 182 1.1 nathanw int 183 1.1 nathanw pthread_attr_setguardsize(pthread_attr_t *attr, size_t guard) 184 1.1 nathanw { 185 1.1 nathanw struct pthread_attr_private *p; 186 1.1 nathanw 187 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 188 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 189 1.19 kamil 190 1.1 nathanw p = pthread__attr_init_private(attr); 191 1.1 nathanw if (p == NULL) 192 1.1 nathanw return ENOMEM; 193 1.1 nathanw 194 1.1 nathanw p->ptap_guardsize = guard; 195 1.1 nathanw 196 1.1 nathanw return 0; 197 1.1 nathanw } 198 1.1 nathanw 199 1.1 nathanw 200 1.1 nathanw int 201 1.1 nathanw pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit) 202 1.1 nathanw { 203 1.1 nathanw 204 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 205 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 206 1.19 kamil 207 1.1 nathanw if (attr->pta_flags & PT_FLAG_EXPLICIT_SCHED) 208 1.1 nathanw *inherit = PTHREAD_EXPLICIT_SCHED; 209 1.1 nathanw else 210 1.1 nathanw *inherit = PTHREAD_INHERIT_SCHED; 211 1.1 nathanw 212 1.1 nathanw return 0; 213 1.1 nathanw } 214 1.1 nathanw 215 1.1 nathanw 216 1.1 nathanw int 217 1.1 nathanw pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit) 218 1.1 nathanw { 219 1.1 nathanw 220 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 221 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 222 1.19 kamil 223 1.1 nathanw switch (inherit) { 224 1.1 nathanw case PTHREAD_INHERIT_SCHED: 225 1.1 nathanw attr->pta_flags &= ~PT_FLAG_EXPLICIT_SCHED; 226 1.1 nathanw break; 227 1.1 nathanw case PTHREAD_EXPLICIT_SCHED: 228 1.1 nathanw attr->pta_flags |= PT_FLAG_EXPLICIT_SCHED; 229 1.1 nathanw break; 230 1.1 nathanw default: 231 1.1 nathanw return EINVAL; 232 1.1 nathanw } 233 1.1 nathanw 234 1.1 nathanw return 0; 235 1.1 nathanw } 236 1.1 nathanw 237 1.1 nathanw 238 1.1 nathanw int 239 1.1 nathanw pthread_attr_getscope(const pthread_attr_t *attr, int *scope) 240 1.1 nathanw { 241 1.1 nathanw 242 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 243 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 244 1.19 kamil 245 1.1 nathanw if (attr->pta_flags & PT_FLAG_SCOPE_SYSTEM) 246 1.1 nathanw *scope = PTHREAD_SCOPE_SYSTEM; 247 1.1 nathanw else 248 1.1 nathanw *scope = PTHREAD_SCOPE_PROCESS; 249 1.1 nathanw 250 1.1 nathanw return 0; 251 1.1 nathanw } 252 1.1 nathanw 253 1.1 nathanw 254 1.1 nathanw int 255 1.1 nathanw pthread_attr_setscope(pthread_attr_t *attr, int scope) 256 1.1 nathanw { 257 1.1 nathanw 258 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 259 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 260 1.19 kamil 261 1.1 nathanw switch (scope) { 262 1.1 nathanw case PTHREAD_SCOPE_PROCESS: 263 1.1 nathanw attr->pta_flags &= ~PT_FLAG_SCOPE_SYSTEM; 264 1.1 nathanw break; 265 1.1 nathanw case PTHREAD_SCOPE_SYSTEM: 266 1.1 nathanw attr->pta_flags |= PT_FLAG_SCOPE_SYSTEM; 267 1.1 nathanw break; 268 1.1 nathanw default: 269 1.1 nathanw return EINVAL; 270 1.1 nathanw } 271 1.1 nathanw 272 1.1 nathanw return 0; 273 1.1 nathanw } 274 1.1 nathanw 275 1.1 nathanw 276 1.1 nathanw int 277 1.1 nathanw pthread_attr_setschedparam(pthread_attr_t *attr, 278 1.10 ad const struct sched_param *param) 279 1.1 nathanw { 280 1.10 ad struct pthread_attr_private *p; 281 1.10 ad int error; 282 1.1 nathanw 283 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 284 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 285 1.19 kamil 286 1.1 nathanw if (param == NULL) 287 1.1 nathanw return EINVAL; 288 1.10 ad p = pthread__attr_init_private(attr); 289 1.10 ad if (p == NULL) 290 1.10 ad return ENOMEM; 291 1.10 ad error = pthread__checkpri(param->sched_priority); 292 1.10 ad if (error == 0) 293 1.10 ad p->ptap_sp = *param; 294 1.10 ad return error; 295 1.1 nathanw } 296 1.1 nathanw 297 1.1 nathanw 298 1.1 nathanw int 299 1.1 nathanw pthread_attr_getschedparam(const pthread_attr_t *attr, 300 1.10 ad struct sched_param *param) 301 1.1 nathanw { 302 1.10 ad struct pthread_attr_private *p; 303 1.1 nathanw 304 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 305 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 306 1.19 kamil 307 1.1 nathanw if (param == NULL) 308 1.1 nathanw return EINVAL; 309 1.10 ad p = attr->pta_private; 310 1.10 ad if (p == NULL) 311 1.11 ad memset(param, 0, sizeof(*param)); 312 1.21 riastrad else 313 1.11 ad *param = p->ptap_sp; 314 1.1 nathanw return 0; 315 1.1 nathanw } 316 1.1 nathanw 317 1.1 nathanw 318 1.1 nathanw int 319 1.10 ad pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy) 320 1.4 nathanw { 321 1.10 ad struct pthread_attr_private *p; 322 1.10 ad 323 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 324 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 325 1.4 nathanw 326 1.10 ad switch (policy) { 327 1.10 ad case SCHED_OTHER: 328 1.10 ad case SCHED_FIFO: 329 1.10 ad case SCHED_RR: 330 1.10 ad p = pthread__attr_init_private(attr); 331 1.10 ad if (p == NULL) 332 1.10 ad return ENOMEM; 333 1.10 ad p->ptap_policy = policy; 334 1.10 ad return 0; 335 1.10 ad default: 336 1.4 nathanw return ENOTSUP; 337 1.10 ad } 338 1.4 nathanw } 339 1.4 nathanw 340 1.4 nathanw 341 1.4 nathanw int 342 1.10 ad pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy) 343 1.4 nathanw { 344 1.10 ad struct pthread_attr_private *p; 345 1.4 nathanw 346 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 347 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 348 1.19 kamil 349 1.10 ad p = attr->pta_private; 350 1.10 ad if (p == NULL) { 351 1.10 ad *policy = SCHED_OTHER; 352 1.10 ad return 0; 353 1.10 ad } 354 1.10 ad *policy = p->ptap_policy; 355 1.4 nathanw return 0; 356 1.4 nathanw } 357 1.4 nathanw 358 1.4 nathanw 359 1.4 nathanw int 360 1.1 nathanw pthread_attr_getstack(const pthread_attr_t *attr, void **addr, size_t *size) 361 1.1 nathanw { 362 1.1 nathanw struct pthread_attr_private *p; 363 1.1 nathanw 364 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 365 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 366 1.19 kamil 367 1.1 nathanw if ((p = attr->pta_private) == NULL) { 368 1.1 nathanw *addr = NULL; 369 1.6 ad *size = pthread__stacksize; 370 1.1 nathanw } else { 371 1.1 nathanw *addr = p->ptap_stackaddr; 372 1.1 nathanw *size = p->ptap_stacksize; 373 1.1 nathanw } 374 1.1 nathanw 375 1.1 nathanw return 0; 376 1.1 nathanw } 377 1.1 nathanw 378 1.1 nathanw 379 1.1 nathanw int 380 1.1 nathanw pthread_attr_setstack(pthread_attr_t *attr, void *addr, size_t size) 381 1.1 nathanw { 382 1.1 nathanw struct pthread_attr_private *p; 383 1.1 nathanw 384 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 385 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 386 1.19 kamil 387 1.1 nathanw p = pthread__attr_init_private(attr); 388 1.1 nathanw if (p == NULL) 389 1.1 nathanw return ENOMEM; 390 1.1 nathanw 391 1.1 nathanw p->ptap_stackaddr = addr; 392 1.1 nathanw p->ptap_stacksize = size; 393 1.1 nathanw 394 1.1 nathanw return 0; 395 1.1 nathanw } 396 1.1 nathanw 397 1.1 nathanw 398 1.1 nathanw int 399 1.1 nathanw pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *size) 400 1.1 nathanw { 401 1.1 nathanw struct pthread_attr_private *p; 402 1.1 nathanw 403 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 404 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 405 1.19 kamil 406 1.1 nathanw if ((p = attr->pta_private) == NULL) 407 1.6 ad *size = pthread__stacksize; 408 1.1 nathanw else 409 1.1 nathanw *size = p->ptap_stacksize; 410 1.1 nathanw 411 1.1 nathanw return 0; 412 1.1 nathanw } 413 1.1 nathanw 414 1.1 nathanw 415 1.1 nathanw int 416 1.1 nathanw pthread_attr_setstacksize(pthread_attr_t *attr, size_t size) 417 1.1 nathanw { 418 1.1 nathanw struct pthread_attr_private *p; 419 1.1 nathanw 420 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 421 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 422 1.19 kamil 423 1.12 lukem if (size < (size_t)sysconf(_SC_THREAD_STACK_MIN)) 424 1.9 ad return EINVAL; 425 1.9 ad 426 1.1 nathanw p = pthread__attr_init_private(attr); 427 1.1 nathanw if (p == NULL) 428 1.1 nathanw return ENOMEM; 429 1.1 nathanw 430 1.1 nathanw p->ptap_stacksize = size; 431 1.1 nathanw 432 1.1 nathanw return 0; 433 1.1 nathanw } 434 1.1 nathanw 435 1.1 nathanw 436 1.1 nathanw int 437 1.1 nathanw pthread_attr_getstackaddr(const pthread_attr_t *attr, void **addr) 438 1.1 nathanw { 439 1.1 nathanw struct pthread_attr_private *p; 440 1.1 nathanw 441 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 442 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 443 1.19 kamil 444 1.1 nathanw if ((p = attr->pta_private) == NULL) 445 1.1 nathanw *addr = NULL; 446 1.1 nathanw else 447 1.1 nathanw *addr = p->ptap_stackaddr; 448 1.1 nathanw 449 1.1 nathanw return 0; 450 1.1 nathanw } 451 1.1 nathanw 452 1.1 nathanw 453 1.1 nathanw int 454 1.1 nathanw pthread_attr_setstackaddr(pthread_attr_t *attr, void *addr) 455 1.1 nathanw { 456 1.1 nathanw struct pthread_attr_private *p; 457 1.1 nathanw 458 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 459 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 460 1.19 kamil 461 1.1 nathanw p = pthread__attr_init_private(attr); 462 1.1 nathanw if (p == NULL) 463 1.1 nathanw return ENOMEM; 464 1.1 nathanw 465 1.1 nathanw p->ptap_stackaddr = addr; 466 1.1 nathanw 467 1.1 nathanw return 0; 468 1.1 nathanw } 469 1.1 nathanw 470 1.1 nathanw 471 1.1 nathanw int 472 1.1 nathanw pthread_attr_getname_np(const pthread_attr_t *attr, char *name, size_t len, 473 1.1 nathanw void **argp) 474 1.1 nathanw { 475 1.1 nathanw struct pthread_attr_private *p; 476 1.1 nathanw 477 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 478 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 479 1.19 kamil 480 1.1 nathanw if ((p = attr->pta_private) == NULL) { 481 1.1 nathanw name[0] = '\0'; 482 1.1 nathanw if (argp != NULL) 483 1.1 nathanw *argp = NULL; 484 1.1 nathanw } else { 485 1.1 nathanw strlcpy(name, p->ptap_name, len); 486 1.1 nathanw if (argp != NULL) 487 1.1 nathanw *argp = p->ptap_namearg; 488 1.1 nathanw } 489 1.1 nathanw 490 1.1 nathanw return 0; 491 1.1 nathanw } 492 1.1 nathanw 493 1.1 nathanw 494 1.1 nathanw int 495 1.1 nathanw pthread_attr_setname_np(pthread_attr_t *attr, const char *name, void *arg) 496 1.1 nathanw { 497 1.1 nathanw struct pthread_attr_private *p; 498 1.1 nathanw int namelen; 499 1.1 nathanw 500 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 501 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 502 1.19 kamil 503 1.1 nathanw p = pthread__attr_init_private(attr); 504 1.1 nathanw if (p == NULL) 505 1.1 nathanw return ENOMEM; 506 1.1 nathanw 507 1.1 nathanw namelen = snprintf(p->ptap_name, PTHREAD_MAX_NAMELEN_NP, name, arg); 508 1.1 nathanw if (namelen >= PTHREAD_MAX_NAMELEN_NP) { 509 1.1 nathanw p->ptap_name[0] = '\0'; 510 1.1 nathanw return EINVAL; 511 1.1 nathanw } 512 1.1 nathanw p->ptap_namearg = arg; 513 1.1 nathanw 514 1.3 christos return 0; 515 1.3 christos } 516 1.3 christos 517 1.3 christos int 518 1.3 christos pthread_attr_setcreatesuspend_np(pthread_attr_t *attr) 519 1.3 christos { 520 1.19 kamil 521 1.19 kamil pthread__error(EINVAL, "Invalid attribute", 522 1.19 kamil attr->pta_magic == PT_ATTR_MAGIC); 523 1.19 kamil 524 1.3 christos attr->pta_flags |= PT_FLAG_SUSPENDED; 525 1.1 nathanw return 0; 526 1.1 nathanw } 527 1.13 christos 528 1.13 christos int 529 1.13 christos pthread_getattr_np(pthread_t thread, pthread_attr_t *attr) 530 1.13 christos { 531 1.13 christos int error; 532 1.19 kamil 533 1.13 christos if ((error = pthread_attr_init(attr)) != 0) 534 1.13 christos return error; 535 1.13 christos if ((error = pthread_attr_get_np(thread, attr)) != 0) { 536 1.13 christos (void)pthread_attr_destroy(attr); 537 1.13 christos return error; 538 1.13 christos } 539 1.13 christos return 0; 540 1.13 christos } 541