Home | History | Annotate | Line # | Download | only in libpthread
pthread_attr.c revision 1.16.24.1
      1  1.16.24.1    bouyer /*	$NetBSD: pthread_attr.c,v 1.16.24.1 2017/08/31 08:32:39 bouyer 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.16.24.1    bouyer __RCSID("$NetBSD: pthread_attr.c,v 1.16.24.1 2017/08/31 08:32:39 bouyer Exp $");
     34        1.1   nathanw 
     35        1.1   nathanw #include <errno.h>
     36        1.1   nathanw #include <stdio.h>
     37        1.1   nathanw #include <stdlib.h>
     38        1.1   nathanw #include <string.h>
     39        1.1   nathanw #include <unistd.h>
     40        1.1   nathanw 
     41       1.14  christos #ifndef __lint__
     42       1.14  christos #define pthread_attr_get_np _pthread_attr_get_np
     43       1.14  christos #endif
     44       1.14  christos 
     45       1.15  christos #include "pthread.h"
     46       1.15  christos #include "pthread_int.h"
     47       1.15  christos 
     48       1.14  christos __weak_alias(pthread_attr_get_np, _pthread_attr_get_np)
     49       1.14  christos 
     50        1.7  christos static struct pthread_attr_private *pthread__attr_init_private(
     51        1.7  christos     pthread_attr_t *);
     52        1.1   nathanw 
     53        1.1   nathanw static struct pthread_attr_private *
     54        1.1   nathanw pthread__attr_init_private(pthread_attr_t *attr)
     55        1.1   nathanw {
     56        1.1   nathanw 	struct pthread_attr_private *p;
     57        1.1   nathanw 
     58        1.1   nathanw 	if ((p = attr->pta_private) != NULL)
     59        1.1   nathanw 		return p;
     60        1.1   nathanw 
     61        1.1   nathanw 	p = malloc(sizeof(*p));
     62        1.1   nathanw 	if (p != NULL) {
     63        1.1   nathanw 		memset(p, 0, sizeof(*p));
     64        1.1   nathanw 		attr->pta_private = p;
     65       1.10        ad 		p->ptap_policy = SCHED_OTHER;
     66        1.1   nathanw 	}
     67        1.1   nathanw 	return p;
     68        1.1   nathanw }
     69        1.1   nathanw 
     70        1.1   nathanw 
     71        1.1   nathanw int
     72        1.1   nathanw pthread_attr_init(pthread_attr_t *attr)
     73        1.1   nathanw {
     74        1.1   nathanw 
     75        1.1   nathanw 	attr->pta_magic = PT_ATTR_MAGIC;
     76        1.1   nathanw 	attr->pta_flags = 0;
     77        1.1   nathanw 	attr->pta_private = NULL;
     78        1.1   nathanw 
     79        1.1   nathanw 	return 0;
     80        1.1   nathanw }
     81        1.1   nathanw 
     82        1.1   nathanw 
     83        1.1   nathanw int
     84        1.1   nathanw pthread_attr_destroy(pthread_attr_t *attr)
     85        1.1   nathanw {
     86        1.1   nathanw 	struct pthread_attr_private *p;
     87        1.1   nathanw 
     88        1.1   nathanw 	if ((p = attr->pta_private) != NULL)
     89        1.1   nathanw 		free(p);
     90        1.1   nathanw 
     91        1.1   nathanw 	return 0;
     92        1.1   nathanw }
     93        1.1   nathanw 
     94        1.1   nathanw 
     95        1.1   nathanw int
     96        1.1   nathanw pthread_attr_get_np(pthread_t thread, pthread_attr_t *attr)
     97        1.1   nathanw {
     98        1.1   nathanw 	struct pthread_attr_private *p;
     99        1.1   nathanw 
    100        1.1   nathanw 	p = pthread__attr_init_private(attr);
    101        1.1   nathanw 	if (p == NULL)
    102        1.1   nathanw 		return ENOMEM;
    103        1.1   nathanw 
    104        1.1   nathanw 	attr->pta_flags = thread->pt_flags &
    105        1.1   nathanw 	    (PT_FLAG_DETACHED | PT_FLAG_SCOPE_SYSTEM | PT_FLAG_EXPLICIT_SCHED);
    106        1.1   nathanw 
    107        1.1   nathanw 	p->ptap_namearg = thread->pt_name;
    108        1.1   nathanw 	p->ptap_stackaddr = thread->pt_stack.ss_sp;
    109        1.1   nathanw 	p->ptap_stacksize = thread->pt_stack.ss_size;
    110  1.16.24.1    bouyer 	p->ptap_guardsize = thread->pt_guardsize;
    111       1.10        ad 	return pthread_getschedparam(thread, &p->ptap_policy, &p->ptap_sp);
    112        1.1   nathanw }
    113        1.1   nathanw 
    114        1.1   nathanw 
    115        1.1   nathanw int
    116        1.1   nathanw pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
    117        1.1   nathanw {
    118        1.1   nathanw 
    119        1.1   nathanw 	if (attr->pta_flags & PT_FLAG_DETACHED)
    120        1.1   nathanw 		*detachstate = PTHREAD_CREATE_DETACHED;
    121        1.1   nathanw 	else
    122        1.1   nathanw 		*detachstate = PTHREAD_CREATE_JOINABLE;
    123        1.1   nathanw 
    124        1.1   nathanw 	return 0;
    125        1.1   nathanw }
    126        1.1   nathanw 
    127        1.1   nathanw 
    128        1.1   nathanw int
    129        1.1   nathanw pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
    130        1.1   nathanw {
    131        1.1   nathanw 
    132        1.1   nathanw 	switch (detachstate) {
    133        1.1   nathanw 	case PTHREAD_CREATE_JOINABLE:
    134        1.1   nathanw 		attr->pta_flags &= ~PT_FLAG_DETACHED;
    135        1.1   nathanw 		break;
    136        1.1   nathanw 	case PTHREAD_CREATE_DETACHED:
    137        1.1   nathanw 		attr->pta_flags |= PT_FLAG_DETACHED;
    138        1.1   nathanw 		break;
    139        1.1   nathanw 	default:
    140        1.1   nathanw 		return EINVAL;
    141        1.1   nathanw 	}
    142        1.1   nathanw 
    143        1.1   nathanw 	return 0;
    144        1.1   nathanw }
    145        1.1   nathanw 
    146        1.1   nathanw 
    147        1.1   nathanw int
    148        1.1   nathanw pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guard)
    149        1.1   nathanw {
    150        1.1   nathanw 	struct pthread_attr_private *p;
    151        1.1   nathanw 
    152        1.1   nathanw 	if ((p = attr->pta_private) == NULL)
    153  1.16.24.1    bouyer 		*guard = pthread__guardsize;
    154        1.1   nathanw 	else
    155        1.1   nathanw 		*guard = p->ptap_guardsize;
    156        1.1   nathanw 
    157        1.1   nathanw 	return 0;
    158        1.1   nathanw }
    159        1.1   nathanw 
    160        1.1   nathanw 
    161        1.1   nathanw int
    162        1.1   nathanw pthread_attr_setguardsize(pthread_attr_t *attr, size_t guard)
    163        1.1   nathanw {
    164        1.1   nathanw 	struct pthread_attr_private *p;
    165        1.1   nathanw 
    166        1.1   nathanw 	p = pthread__attr_init_private(attr);
    167        1.1   nathanw 	if (p == NULL)
    168        1.1   nathanw 		return ENOMEM;
    169        1.1   nathanw 
    170        1.1   nathanw 	p->ptap_guardsize = guard;
    171        1.1   nathanw 
    172        1.1   nathanw 	return 0;
    173        1.1   nathanw }
    174        1.1   nathanw 
    175        1.1   nathanw 
    176        1.1   nathanw int
    177        1.1   nathanw pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit)
    178        1.1   nathanw {
    179        1.1   nathanw 
    180        1.1   nathanw 	if (attr->pta_flags & PT_FLAG_EXPLICIT_SCHED)
    181        1.1   nathanw 		*inherit = PTHREAD_EXPLICIT_SCHED;
    182        1.1   nathanw 	else
    183        1.1   nathanw 		*inherit = PTHREAD_INHERIT_SCHED;
    184        1.1   nathanw 
    185        1.1   nathanw 	return 0;
    186        1.1   nathanw }
    187        1.1   nathanw 
    188        1.1   nathanw 
    189        1.1   nathanw int
    190        1.1   nathanw pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit)
    191        1.1   nathanw {
    192        1.1   nathanw 
    193        1.1   nathanw 	switch (inherit) {
    194        1.1   nathanw 	case PTHREAD_INHERIT_SCHED:
    195        1.1   nathanw 		attr->pta_flags &= ~PT_FLAG_EXPLICIT_SCHED;
    196        1.1   nathanw 		break;
    197        1.1   nathanw 	case PTHREAD_EXPLICIT_SCHED:
    198        1.1   nathanw 		attr->pta_flags |= PT_FLAG_EXPLICIT_SCHED;
    199        1.1   nathanw 		break;
    200        1.1   nathanw 	default:
    201        1.1   nathanw 		return EINVAL;
    202        1.1   nathanw 	}
    203        1.1   nathanw 
    204        1.1   nathanw 	return 0;
    205        1.1   nathanw }
    206        1.1   nathanw 
    207        1.1   nathanw 
    208        1.1   nathanw int
    209        1.1   nathanw pthread_attr_getscope(const pthread_attr_t *attr, int *scope)
    210        1.1   nathanw {
    211        1.1   nathanw 
    212        1.1   nathanw 	if (attr->pta_flags & PT_FLAG_SCOPE_SYSTEM)
    213        1.1   nathanw 		*scope = PTHREAD_SCOPE_SYSTEM;
    214        1.1   nathanw 	else
    215        1.1   nathanw 		*scope = PTHREAD_SCOPE_PROCESS;
    216        1.1   nathanw 
    217        1.1   nathanw 	return 0;
    218        1.1   nathanw }
    219        1.1   nathanw 
    220        1.1   nathanw 
    221        1.1   nathanw int
    222        1.1   nathanw pthread_attr_setscope(pthread_attr_t *attr, int scope)
    223        1.1   nathanw {
    224        1.1   nathanw 
    225        1.1   nathanw 	switch (scope) {
    226        1.1   nathanw 	case PTHREAD_SCOPE_PROCESS:
    227        1.1   nathanw 		attr->pta_flags &= ~PT_FLAG_SCOPE_SYSTEM;
    228        1.1   nathanw 		break;
    229        1.1   nathanw 	case PTHREAD_SCOPE_SYSTEM:
    230        1.1   nathanw 		attr->pta_flags |= PT_FLAG_SCOPE_SYSTEM;
    231        1.1   nathanw 		break;
    232        1.1   nathanw 	default:
    233        1.1   nathanw 		return EINVAL;
    234        1.1   nathanw 	}
    235        1.1   nathanw 
    236        1.1   nathanw 	return 0;
    237        1.1   nathanw }
    238        1.1   nathanw 
    239        1.1   nathanw 
    240        1.1   nathanw int
    241        1.1   nathanw pthread_attr_setschedparam(pthread_attr_t *attr,
    242       1.10        ad 			   const struct sched_param *param)
    243        1.1   nathanw {
    244       1.10        ad 	struct pthread_attr_private *p;
    245       1.10        ad 	int error;
    246        1.1   nathanw 
    247        1.1   nathanw 	if (param == NULL)
    248        1.1   nathanw 		return EINVAL;
    249       1.10        ad 	p = pthread__attr_init_private(attr);
    250       1.10        ad 	if (p == NULL)
    251       1.10        ad 		return ENOMEM;
    252       1.10        ad 	error = pthread__checkpri(param->sched_priority);
    253       1.10        ad 	if (error == 0)
    254       1.10        ad 		p->ptap_sp = *param;
    255       1.10        ad 	return error;
    256        1.1   nathanw }
    257        1.1   nathanw 
    258        1.1   nathanw 
    259        1.1   nathanw int
    260        1.1   nathanw pthread_attr_getschedparam(const pthread_attr_t *attr,
    261       1.10        ad 			   struct sched_param *param)
    262        1.1   nathanw {
    263       1.10        ad 	struct pthread_attr_private *p;
    264        1.1   nathanw 
    265        1.1   nathanw 	if (param == NULL)
    266        1.1   nathanw 		return EINVAL;
    267       1.10        ad 	p = attr->pta_private;
    268       1.10        ad 	if (p == NULL)
    269       1.11        ad 		memset(param, 0, sizeof(*param));
    270       1.11        ad 	else
    271       1.11        ad 		*param = p->ptap_sp;
    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.10        ad pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
    278        1.4   nathanw {
    279       1.10        ad 	struct pthread_attr_private *p;
    280       1.10        ad 
    281        1.4   nathanw 
    282       1.10        ad 	switch (policy) {
    283       1.10        ad 	case SCHED_OTHER:
    284       1.10        ad 	case SCHED_FIFO:
    285       1.10        ad 	case SCHED_RR:
    286       1.10        ad 		p = pthread__attr_init_private(attr);
    287       1.10        ad 		if (p == NULL)
    288       1.10        ad 			return ENOMEM;
    289       1.10        ad 		p->ptap_policy = policy;
    290       1.10        ad 		return 0;
    291       1.10        ad 	default:
    292        1.4   nathanw 		return ENOTSUP;
    293       1.10        ad 	}
    294        1.4   nathanw }
    295        1.4   nathanw 
    296        1.4   nathanw 
    297        1.4   nathanw int
    298       1.10        ad pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
    299        1.4   nathanw {
    300       1.10        ad 	struct pthread_attr_private *p;
    301        1.4   nathanw 
    302       1.10        ad 	p = attr->pta_private;
    303       1.10        ad 	if (p == NULL) {
    304       1.10        ad 		*policy = SCHED_OTHER;
    305       1.10        ad 		return 0;
    306       1.10        ad 	}
    307       1.10        ad 	*policy = p->ptap_policy;
    308        1.4   nathanw 	return 0;
    309        1.4   nathanw }
    310        1.4   nathanw 
    311        1.4   nathanw 
    312        1.4   nathanw int
    313        1.1   nathanw pthread_attr_getstack(const pthread_attr_t *attr, void **addr, size_t *size)
    314        1.1   nathanw {
    315        1.1   nathanw 	struct pthread_attr_private *p;
    316        1.1   nathanw 
    317        1.1   nathanw 	if ((p = attr->pta_private) == NULL) {
    318        1.1   nathanw 		*addr = NULL;
    319        1.6        ad 		*size = pthread__stacksize;
    320        1.1   nathanw 	} else {
    321        1.1   nathanw 		*addr = p->ptap_stackaddr;
    322        1.1   nathanw 		*size = p->ptap_stacksize;
    323        1.1   nathanw 	}
    324        1.1   nathanw 
    325        1.1   nathanw 	return 0;
    326        1.1   nathanw }
    327        1.1   nathanw 
    328        1.1   nathanw 
    329        1.1   nathanw int
    330        1.1   nathanw pthread_attr_setstack(pthread_attr_t *attr, void *addr, size_t size)
    331        1.1   nathanw {
    332        1.1   nathanw 	struct pthread_attr_private *p;
    333        1.1   nathanw 
    334        1.1   nathanw 	p = pthread__attr_init_private(attr);
    335        1.1   nathanw 	if (p == NULL)
    336        1.1   nathanw 		return ENOMEM;
    337        1.1   nathanw 
    338        1.1   nathanw 	p->ptap_stackaddr = addr;
    339        1.1   nathanw 	p->ptap_stacksize = size;
    340        1.1   nathanw 
    341        1.1   nathanw 	return 0;
    342        1.1   nathanw }
    343        1.1   nathanw 
    344        1.1   nathanw 
    345        1.1   nathanw int
    346        1.1   nathanw pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *size)
    347        1.1   nathanw {
    348        1.1   nathanw 	struct pthread_attr_private *p;
    349        1.1   nathanw 
    350        1.1   nathanw 	if ((p = attr->pta_private) == NULL)
    351        1.6        ad 		*size = pthread__stacksize;
    352        1.1   nathanw 	else
    353        1.1   nathanw 		*size = p->ptap_stacksize;
    354        1.1   nathanw 
    355        1.1   nathanw 	return 0;
    356        1.1   nathanw }
    357        1.1   nathanw 
    358        1.1   nathanw 
    359        1.1   nathanw int
    360        1.1   nathanw pthread_attr_setstacksize(pthread_attr_t *attr, size_t size)
    361        1.1   nathanw {
    362        1.1   nathanw 	struct pthread_attr_private *p;
    363        1.1   nathanw 
    364       1.12     lukem 	if (size < (size_t)sysconf(_SC_THREAD_STACK_MIN))
    365        1.9        ad 		return EINVAL;
    366        1.9        ad 
    367        1.1   nathanw 	p = pthread__attr_init_private(attr);
    368        1.1   nathanw 	if (p == NULL)
    369        1.1   nathanw 		return ENOMEM;
    370        1.1   nathanw 
    371        1.1   nathanw 	p->ptap_stacksize = size;
    372        1.1   nathanw 
    373        1.1   nathanw 	return 0;
    374        1.1   nathanw }
    375        1.1   nathanw 
    376        1.1   nathanw 
    377        1.1   nathanw int
    378        1.1   nathanw pthread_attr_getstackaddr(const pthread_attr_t *attr, void **addr)
    379        1.1   nathanw {
    380        1.1   nathanw 	struct pthread_attr_private *p;
    381        1.1   nathanw 
    382        1.1   nathanw 	if ((p = attr->pta_private) == NULL)
    383        1.1   nathanw 		*addr = NULL;
    384        1.1   nathanw 	else
    385        1.1   nathanw 		*addr = p->ptap_stackaddr;
    386        1.1   nathanw 
    387        1.1   nathanw 	return 0;
    388        1.1   nathanw }
    389        1.1   nathanw 
    390        1.1   nathanw 
    391        1.1   nathanw int
    392        1.1   nathanw pthread_attr_setstackaddr(pthread_attr_t *attr, void *addr)
    393        1.1   nathanw {
    394        1.1   nathanw 	struct pthread_attr_private *p;
    395        1.1   nathanw 
    396        1.1   nathanw 	p = pthread__attr_init_private(attr);
    397        1.1   nathanw 	if (p == NULL)
    398        1.1   nathanw 		return ENOMEM;
    399        1.1   nathanw 
    400        1.1   nathanw 	p->ptap_stackaddr = addr;
    401        1.1   nathanw 
    402        1.1   nathanw 	return 0;
    403        1.1   nathanw }
    404        1.1   nathanw 
    405        1.1   nathanw 
    406        1.1   nathanw int
    407        1.1   nathanw pthread_attr_getname_np(const pthread_attr_t *attr, char *name, size_t len,
    408        1.1   nathanw     void **argp)
    409        1.1   nathanw {
    410        1.1   nathanw 	struct pthread_attr_private *p;
    411        1.1   nathanw 
    412        1.1   nathanw 	if ((p = attr->pta_private) == NULL) {
    413        1.1   nathanw 		name[0] = '\0';
    414        1.1   nathanw 		if (argp != NULL)
    415        1.1   nathanw 			*argp = NULL;
    416        1.1   nathanw 	} else {
    417        1.1   nathanw 		strlcpy(name, p->ptap_name, len);
    418        1.1   nathanw 		if (argp != NULL)
    419        1.1   nathanw 			*argp = p->ptap_namearg;
    420        1.1   nathanw 	}
    421        1.1   nathanw 
    422        1.1   nathanw 	return 0;
    423        1.1   nathanw }
    424        1.1   nathanw 
    425        1.1   nathanw 
    426        1.1   nathanw int
    427        1.1   nathanw pthread_attr_setname_np(pthread_attr_t *attr, const char *name, void *arg)
    428        1.1   nathanw {
    429        1.1   nathanw 	struct pthread_attr_private *p;
    430        1.1   nathanw 	int namelen;
    431        1.1   nathanw 
    432        1.1   nathanw 	p = pthread__attr_init_private(attr);
    433        1.1   nathanw 	if (p == NULL)
    434        1.1   nathanw 		return ENOMEM;
    435        1.1   nathanw 
    436        1.1   nathanw 	namelen = snprintf(p->ptap_name, PTHREAD_MAX_NAMELEN_NP, name, arg);
    437        1.1   nathanw 	if (namelen >= PTHREAD_MAX_NAMELEN_NP) {
    438        1.1   nathanw 		p->ptap_name[0] = '\0';
    439        1.1   nathanw 		return EINVAL;
    440        1.1   nathanw 	}
    441        1.1   nathanw 	p->ptap_namearg = arg;
    442        1.1   nathanw 
    443        1.3  christos 	return 0;
    444        1.3  christos }
    445        1.3  christos 
    446        1.3  christos int
    447        1.3  christos pthread_attr_setcreatesuspend_np(pthread_attr_t *attr)
    448        1.3  christos {
    449        1.3  christos 	attr->pta_flags |= PT_FLAG_SUSPENDED;
    450        1.1   nathanw 	return 0;
    451        1.1   nathanw }
    452       1.13  christos 
    453       1.13  christos int
    454       1.13  christos pthread_getattr_np(pthread_t thread, pthread_attr_t *attr)
    455       1.13  christos {
    456       1.13  christos 	int error;
    457       1.13  christos 	if ((error = pthread_attr_init(attr)) != 0)
    458       1.13  christos 		return error;
    459       1.13  christos 	if ((error = pthread_attr_get_np(thread, attr)) != 0) {
    460       1.13  christos 		(void)pthread_attr_destroy(attr);
    461       1.13  christos 		return error;
    462       1.13  christos 	}
    463       1.13  christos 	return 0;
    464       1.13  christos }
    465