[BACK]Return to pthread_attr.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libpthread

Annotation of src/lib/libpthread/pthread_attr.c, Revision 1.13

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

CVSweb <webmaster@jp.NetBSD.org>