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

Annotation of src/lib/libpthread/pthread_int.h, Revision 1.34.4.1

1.34.4.1! wrstuden    1: /*     $NetBSD: pthread_int.h,v 1.34 2006/10/03 09:37:07 yamt Exp $    */
1.2       thorpej     2:
                      3: /*-
1.16      nathanw     4:  * Copyright (c) 2001,2002,2003 The NetBSD Foundation, Inc.
1.2       thorpej     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:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *        This product includes software developed by the NetBSD
                     21:  *        Foundation, Inc. and its contributors.
                     22:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     23:  *    contributors may be used to endorse or promote products derived
                     24:  *    from this software without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     27:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     36:  * POSSIBILITY OF SUCH DAMAGE.
                     37:  */
                     38:
                     39: #ifndef _LIB_PTHREAD_INT_H
                     40: #define _LIB_PTHREAD_INT_H
                     41:
                     42: #define PTHREAD__DEBUG
                     43: #define ERRORCHECK
                     44:
                     45: #include "pthread_types.h"
                     46: #include "pthread_queue.h"
                     47: #include "pthread_debug.h"
                     48: #include "pthread_md.h"
                     49:
                     50: #include <sa.h>
                     51: #include <signal.h>
                     52:
1.15      nathanw    53: #define PTHREAD_KEYS_MAX 256
1.2       thorpej    54: /*
                     55:  * The size of this structure needs to be no larger than struct
                     56:  * __pthread_cleanup_store, defined in pthread.h.
                     57:  */
                     58: struct pt_clean_t {
                     59:        PTQ_ENTRY(pt_clean_t)   ptc_next;
                     60:        void    (*ptc_cleanup)(void *);
                     61:        void    *ptc_arg;
                     62: };
                     63:
                     64: struct pt_alarm_t {
                     65:        PTQ_ENTRY(pt_alarm_t)   pta_next;
                     66:        pthread_spin_t  pta_lock;
                     67:        const struct timespec   *pta_time;
                     68:        void    (*pta_func)(void *);
                     69:        void    *pta_arg;
                     70:        int     pta_fired;
1.16      nathanw    71: };
                     72:
                     73: /* Private data for pthread_attr_t */
                     74: struct pthread_attr_private {
                     75:        char ptap_name[PTHREAD_MAX_NAMELEN_NP];
                     76:        void *ptap_namearg;
                     77:        void *ptap_stackaddr;
                     78:        size_t ptap_stacksize;
                     79:        size_t ptap_guardsize;
1.2       thorpej    80: };
                     81:
1.15      nathanw    82: struct __pthread_st {
1.2       thorpej    83:        unsigned int    pt_magic;
1.4       nathanw    84:        /* Identifier, for debugging and for preventing recycling. */
                     85:        int             pt_num;
1.2       thorpej    86:
                     87:        int     pt_type;        /* normal, upcall, or idle */
                     88:        int     pt_state;       /* running, blocked, etc. */
                     89:        pthread_spin_t pt_statelock;    /* lock on pt_state */
                     90:        int     pt_flags;       /* see PT_FLAG_* below */
1.17      nathanw    91:        pthread_spin_t pt_flaglock;     /* lock on pt_flag */
1.2       thorpej    92:        int     pt_cancel;      /* Deferred cancellation */
                     93:        int     pt_spinlocks;   /* Number of spinlocks held. */
                     94:        int     pt_blockedlwp;  /* LWP/SA number when blocked */
1.26      cl         95:        int     pt_vpid;        /* VP number */
1.23      cl         96:        int     pt_blockgen;    /* SA_UPCALL_BLOCKED counter */
                     97:        int     pt_unblockgen;  /* SA_UPCALL_UNBLOCKED counter */
1.2       thorpej    98:
                     99:        int     pt_errno;       /* Thread-specific errno. */
                    100:
                    101:        /* Entry on the run queue */
1.15      nathanw   102:        PTQ_ENTRY(__pthread_st) pt_runq;
1.2       thorpej   103:        /* Entry on the list of all threads */
1.15      nathanw   104:        PTQ_ENTRY(__pthread_st) pt_allq;
1.2       thorpej   105:        /* Entry on the sleep queue (xxx should be same as run queue?) */
1.15      nathanw   106:        PTQ_ENTRY(__pthread_st) pt_sleep;
1.2       thorpej   107:        /* Object we're sleeping on */
1.6       jdolecek  108:        void                    *pt_sleepobj;
1.2       thorpej   109:        /* Queue we're sleeping on */
1.6       jdolecek  110:        struct pthread_queue_t  *pt_sleepq;
1.2       thorpej   111:        /* Lock protecting that queue */
                    112:        pthread_spin_t          *pt_sleeplock;
                    113:
                    114:        stack_t         pt_stack;       /* Our stack */
                    115:        ucontext_t      *pt_uc;         /* Saved context when we're stopped */
1.14      nathanw   116:        ucontext_t      *pt_trapuc;     /* Kernel-saved context */
1.30      mycroft   117:        ucontext_t      *__pt_blockuc;  /* Kernel-saved context when blocked */
1.2       thorpej   118:
                    119:        sigset_t        pt_sigmask;     /* Signals we won't take. */
                    120:        sigset_t        pt_siglist;     /* Signals pending for us. */
1.4       nathanw   121:        sigset_t        pt_sigblocked;  /* Signals delivered while blocked. */
1.8       jdolecek  122:        sigset_t        *pt_sigwait;    /* Signals waited for in sigwait */
                    123:        siginfo_t       *pt_wsig;
1.2       thorpej   124:        pthread_spin_t  pt_siglock;     /* Lock on above */
                    125:
                    126:        void *          pt_exitval;     /* Read by pthread_join() */
                    127:
                    128:        /* Stack of cancellation cleanup handlers and their arguments */
                    129:        PTQ_HEAD(, pt_clean_t)  pt_cleanup_stack;
                    130:
1.9       thorpej   131:        /* Thread's name, set by the application. */
                    132:        char*           pt_name;
                    133:
1.2       thorpej   134:        /* Other threads trying to pthread_join() us. */
                    135:        struct pthread_queue_t  pt_joiners;
                    136:        /* Lock for above, and for changing pt_state to ZOMBIE or DEAD,
1.9       thorpej   137:         * and for setting the DETACHED flag.  Also protects pt_name.
1.2       thorpej   138:         */
                    139:        pthread_spin_t  pt_join_lock;
                    140:
                    141:        /* Thread we were going to switch to before we were preempted
                    142:         * ourselves. Will be used by the upcall that's continuing us.
                    143:         */
                    144:        pthread_t       pt_switchto;
                    145:        ucontext_t*     pt_switchtouc;
                    146:
                    147:        /* Threads that are preempted with spinlocks held will be
                    148:         * continued until they unlock their spinlock. When they do
                    149:         * so, they should jump ship to the thread pointed to by
                    150:         * pt_next.
                    151:         */
                    152:        pthread_t       pt_next;
                    153:
                    154:        /* The upcall that is continuing this thread */
                    155:        pthread_t       pt_parent;
                    156:
                    157:        /* A queue lock that this thread held while trying to
                    158:         * context switch to another process.
                    159:         */
                    160:        pthread_spin_t* pt_heldlock;
                    161:
1.24      cl        162:        /* Upcall stack information shared between kernel and
                    163:         * userland.
                    164:         */
                    165:        struct sa_stackinfo_t   pt_stackinfo;
                    166:
1.2       thorpej   167:        /* Thread-specific data */
                    168:        void*           pt_specific[PTHREAD_KEYS_MAX];
                    169:
                    170: #ifdef PTHREAD__DEBUG
                    171:        int     blocks;
                    172:        int     preempts;
                    173:        int     rescheds;
                    174: #endif
                    175: };
                    176:
                    177: struct pthread_lock_ops {
                    178:        void    (*plo_init)(__cpu_simple_lock_t *);
                    179:        int     (*plo_try)(__cpu_simple_lock_t *);
                    180:        void    (*plo_unlock)(__cpu_simple_lock_t *);
                    181: };
                    182:
                    183: /* Thread types */
                    184: #define PT_THREAD_NORMAL       1
                    185: #define PT_THREAD_UPCALL       2
                    186: #define PT_THREAD_IDLE         3
                    187:
                    188: /* Thread states */
                    189: #define PT_STATE_RUNNING       1
                    190: #define PT_STATE_RUNNABLE      2
1.23      cl        191: #define _PT_STATE_BLOCKED_SYS  3       /* Only used in libpthread_dbg */
1.2       thorpej   192: #define PT_STATE_BLOCKED_QUEUE 4
                    193: #define PT_STATE_ZOMBIE                5
                    194: #define PT_STATE_DEAD          6
1.20      christos  195: #define PT_STATE_SUSPENDED     7
1.2       thorpej   196:
                    197: /* Flag values */
                    198:
                    199: #define PT_FLAG_DETACHED       0x0001
                    200: #define PT_FLAG_IDLED          0x0002
                    201: #define PT_FLAG_CS_DISABLED    0x0004  /* Cancellation disabled */
                    202: #define PT_FLAG_CS_ASYNC       0x0008  /* Cancellation is async */
                    203: #define PT_FLAG_CS_PENDING     0x0010
1.4       nathanw   204: #define PT_FLAG_SIGDEFERRED     0x0020 /* There are signals to take */
1.15      nathanw   205: #define PT_FLAG_SCOPE_SYSTEM   0x0040
                    206: #define PT_FLAG_EXPLICIT_SCHED 0x0080
1.29      nathanw   207: #define PT_FLAG_SUSPENDED      0x0100  /* In the suspended queue */
1.28      nathanw   208: #define PT_FLAG_SIGNALED       0x0200
1.2       thorpej   209:
                    210: #define PT_MAGIC       0x11110001
                    211: #define PT_DEAD                0xDEAD0001
                    212:
                    213: #define PT_ATTR_MAGIC  0x22220002
                    214: #define PT_ATTR_DEAD   0xDEAD0002
                    215:
1.22      cl        216: #ifdef PT_FIXEDSTACKSIZE_LG
                    217:
                    218: #define        PT_STACKSIZE_LG PT_FIXEDSTACKSIZE_LG
                    219: #define        PT_STACKSIZE    (1<<(PT_STACKSIZE_LG))
                    220: #define        PT_STACKMASK    (PT_STACKSIZE-1)
                    221:
                    222: #else  /* PT_FIXEDSTACKSIZE_LG */
                    223:
1.25      nathanw   224: extern int             pthread_stacksize_lg;
                    225: extern size_t          pthread_stacksize;
                    226: extern vaddr_t         pthread_stackmask;
                    227:
                    228: #define        PT_STACKSIZE_LG pthread_stacksize_lg
                    229: #define        PT_STACKSIZE    pthread_stacksize
                    230: #define        PT_STACKMASK    pthread_stackmask
1.22      cl        231:
                    232: #endif /* PT_FIXEDSTACKSIZE_LG */
                    233:
1.2       thorpej   234:
                    235: #define PT_UPCALLSTACKS        16
                    236:
                    237: #define PT_ALARMTIMER_MAGIC    0x88880010
                    238: #define PT_RRTIMER_MAGIC       0x88880020
                    239: #define NIDLETHREADS   4
                    240:
                    241: /* Flag to be used in a ucontext_t's uc_flags indicating that
                    242:  * the saved register state is "user" state only, not full
                    243:  * trap state.
                    244:  */
                    245: #define _UC_USER_BIT           30
                    246: #define _UC_USER               (1LU << _UC_USER_BIT)
                    247:
                    248: void   pthread_init(void)  __attribute__ ((__constructor__));
                    249:
                    250: /* Utility functions */
                    251:
                    252: /* Set up/clean up a thread's basic state. */
                    253: void   pthread__initthread(pthread_t self, pthread_t t);
1.24      cl        254: /* Get offset from stack start to struct sa_stackinfo */
                    255: ssize_t        pthread__stackinfo_offset(void);
1.2       thorpej   256:
                    257: /* Go do something else. Don't go back on the run queue */
                    258: void   pthread__block(pthread_t self, pthread_spin_t* queuelock);
1.20      christos  259: /* Put a thread back on the suspended queue */
                    260: void   pthread__suspend(pthread_t self, pthread_t thread);
1.2       thorpej   261: /* Put a thread back on the run queue */
                    262: void   pthread__sched(pthread_t self, pthread_t thread);
1.5       nathanw   263: void   pthread__sched_sleepers(pthread_t self, struct pthread_queue_t *threadq);
1.2       thorpej   264: void   pthread__sched_idle(pthread_t self, pthread_t thread);
                    265: void   pthread__sched_idle2(pthread_t self);
                    266:
                    267: void   pthread__sched_bulk(pthread_t self, pthread_t qhead);
                    268:
                    269: void   pthread__idle(void);
                    270:
                    271: /* Get the next thread */
                    272: pthread_t pthread__next(pthread_t self);
                    273:
                    274: int    pthread__stackalloc(pthread_t *t);
                    275: void   pthread__initmain(pthread_t *t);
                    276:
                    277: void   pthread__sa_start(void);
                    278: void   pthread__sa_recycle(pthread_t old, pthread_t new);
1.26      cl        279: void   pthread__setconcurrency(int);
1.2       thorpej   280:
                    281: /* Alarm code */
                    282: void   pthread__alarm_init(void);
                    283: void   pthread__alarm_add(pthread_t, struct pt_alarm_t *,
                    284:     const struct timespec *, void (*)(void *), void *);
                    285: void   pthread__alarm_del(pthread_t, struct pt_alarm_t *);
                    286: int    pthread__alarm_fired(struct pt_alarm_t *);
                    287: void   pthread__alarm_process(pthread_t self, void *arg);
                    288:
                    289: /* Internal locking primitives */
1.26      cl        290: void   pthread__lockprim_init(int ncpu);
1.2       thorpej   291: void   pthread_lockinit(pthread_spin_t *lock);
                    292: void   pthread_spinlock(pthread_t thread, pthread_spin_t *lock);
                    293: int    pthread_spintrylock(pthread_t thread, pthread_spin_t *lock);
                    294: void   pthread_spinunlock(pthread_t thread, pthread_spin_t *lock);
                    295:
                    296: extern const struct pthread_lock_ops *pthread__lock_ops;
                    297:
                    298: #define        pthread__simple_lock_init(alp)  (*pthread__lock_ops->plo_init)(alp)
                    299: #define        pthread__simple_lock_try(alp)   (*pthread__lock_ops->plo_try)(alp)
                    300: #define        pthread__simple_unlock(alp)     (*pthread__lock_ops->plo_unlock)(alp)
                    301:
                    302: #ifndef _getcontext_u
                    303: int    _getcontext_u(ucontext_t *);
                    304: #endif
                    305: #ifndef _setcontext_u
                    306: int    _setcontext_u(const ucontext_t *);
                    307: #endif
                    308: #ifndef _swapcontext_u
                    309: int    _swapcontext_u(ucontext_t *, const ucontext_t *);
                    310: #endif
                    311:
                    312: void   pthread__testcancel(pthread_t self);
                    313: int    pthread__find(pthread_t self, pthread_t target);
                    314:
                    315: #ifndef PTHREAD_MD_INIT
                    316: #define PTHREAD_MD_INIT
                    317: #endif
                    318:
                    319: #ifndef _INITCONTEXT_U_MD
                    320: #define _INITCONTEXT_U_MD(ucp)
                    321: #endif
                    322:
                    323: #define _INITCONTEXT_U(ucp) do {                                       \
                    324:        (ucp)->uc_flags = _UC_CPU | _UC_STACK;                          \
                    325:        _INITCONTEXT_U_MD(ucp)                                          \
1.3       christos  326:        } while (/*CONSTCOND*/0)
1.2       thorpej   327:
1.13      nathanw   328: #ifdef PTHREAD_MACHINE_HAS_ID_REGISTER
                    329: #define pthread__id(reg) (reg)
                    330: #else
1.2       thorpej   331: /* Stack location of pointer to a particular thread */
                    332: #define pthread__id(sp) \
                    333:        ((pthread_t) (((vaddr_t)(sp)) & ~PT_STACKMASK))
                    334:
1.13      nathanw   335: #define pthread__id_reg() pthread__sp()
                    336: #endif
                    337:
                    338: #define pthread__self() (pthread__id(pthread__id_reg()))
1.2       thorpej   339:
1.12      christos  340: #define pthread__abort()                                               \
                    341:        pthread__assertfunc(__FILE__, __LINE__, __func__, "unreachable")
                    342:
1.11      nathanw   343: #define pthread__assert(e) do {                                                \
                    344:        if (__predict_false(!(e)))                                      \
                    345:                       pthread__assertfunc(__FILE__, __LINE__, __func__, #e);   \
1.12      christos  346:         } while (/*CONSTCOND*/0)
1.11      nathanw   347:
                    348: #define pthread__error(err, msg, e) do {                               \
                    349:        if (__predict_false(!(e))) {                                    \
                    350:                       pthread__errorfunc(__FILE__, __LINE__, __func__, msg);   \
                    351:               return (err);                                            \
                    352:        }                                                               \
1.12      christos  353:         } while (/*CONSTCOND*/0)
1.11      nathanw   354:
1.34.4.1! wrstuden  355: /*
        !           356:  * You must hold t->pt_statelock when making this check.
        !           357:  */
        !           358: #define pthread_check_defsig(t)                                        \
        !           359:        __predict_false((t)->pt_flags & PT_FLAG_SIGDEFERRED)
        !           360:
1.7       nathanw   361:
                    362:
1.2       thorpej   363: /* These three routines are defined in processor-specific code. */
                    364: void   pthread__upcall_switch(pthread_t self, pthread_t next);
                    365: void   pthread__switch(pthread_t self, pthread_t next);
                    366: void   pthread__locked_switch(pthread_t self, pthread_t next,
                    367:     pthread_spin_t *lock);
                    368:
                    369: void   pthread__signal_init(void);
1.31      nathanw   370: void   pthread__signal_start(void);
1.2       thorpej   371:
1.19      christos  372: void   pthread__signal(pthread_t self, pthread_t t, siginfo_t *si);
                    373: void   pthread__deliver_signal(pthread_t self, pthread_t t, siginfo_t *si);
1.4       nathanw   374: void   pthread__signal_deferred(pthread_t self, pthread_t t);
1.2       thorpej   375:
                    376: void   pthread__destroy_tsd(pthread_t self);
1.27      drochner  377: void   pthread__assertfunc(const char *file, int line, const char *function,
                    378:                const char *expr);
                    379: void   pthread__errorfunc(const char *file, int line, const char *function,
                    380:                const char *msg);
1.2       thorpej   381:
                    382: #endif /* _LIB_PTHREAD_INT_H */

CVSweb <webmaster@jp.NetBSD.org>