[BACK]Return to reentrant.h CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / include

Annotation of src/lib/libc/include/reentrant.h, Revision 1.16

1.16    ! christos    1: /*     $NetBSD: reentrant.h,v 1.15 2012/06/03 21:27:30 joerg Exp $     */
1.5       kleink      2:
1.1       jtc         3: /*-
1.7       thorpej     4:  * Copyright (c) 1997, 1998, 2003 The NetBSD Foundation, Inc.
1.1       jtc         5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
1.7       thorpej     8:  * by J.T. Conklin, by Nathan J. Williams, and by Jason R. Thorpe.
1.1       jtc         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: /*
                     33:  * Requirements:
                     34:  *
                     35:  * 1. The thread safe mechanism should be lightweight so the library can
                     36:  *    be used by non-threaded applications without unreasonable overhead.
                     37:  *
                     38:  * 2. There should be no dependency on a thread engine for non-threaded
                     39:  *    applications.
                     40:  *
                     41:  * 3. There should be no dependency on any particular thread engine.
                     42:  *
                     43:  * 4. The library should be able to be compiled without support for thread
                     44:  *    safety.
                     45:  *
                     46:  *
                     47:  * Rationale:
                     48:  *
                     49:  * One approach for thread safety is to provide discrete versions of the
                     50:  * library: one thread safe, the other not.  The disadvantage of this is
                     51:  * that libc is rather large, and two copies of a library which are 99%+
                     52:  * identical is not an efficent use of resources.
                     53:  *
                     54:  * Another approach is to provide a single thread safe library.  However,
                     55:  * it should not add significant run time or code size overhead to non-
                     56:  * threaded applications.
                     57:  *
                     58:  * Since the NetBSD C library is used in other projects, it should be
                     59:  * easy to replace the mutual exclusion primitives with ones provided by
                     60:  * another system.  Similarly, it should also be easy to remove all
                     61:  * support for thread safety completely if the target environment does
                     62:  * not support threads.
                     63:  *
                     64:  *
                     65:  * Implementation Details:
                     66:  *
1.7       thorpej    67:  * The thread primitives used by the library (mutex_t, mutex_lock, etc.)
1.1       jtc        68:  * are macros which expand to the cooresponding primitives provided by
                     69:  * the thread engine or to nothing.  The latter is used so that code is
                     70:  * not unreasonably cluttered with #ifdefs when all thread safe support
                     71:  * is removed.
                     72:  *
1.7       thorpej    73:  * The thread macros can be directly mapped to the mutex primitives from
1.1       jtc        74:  * pthreads, however it should be reasonably easy to wrap another mutex
                     75:  * implementation so it presents a similar interface.
                     76:  *
1.7       thorpej    77:  * The thread functions operate by dispatching to symbols which are, by
                     78:  * default, weak-aliased to no-op functions in thread-stub/thread-stub.c
                     79:  * (some uses of thread operations are conditional on __isthreaded, but
                     80:  * not all of them are).
                     81:  *
                     82:  * When the thread library is linked in, it provides strong-alias versions
                     83:  * of those symbols which dispatch to its own real thread operations.
1.8       thorpej    84:  *
1.1       jtc        85:  */
                     86:
1.10      nathanw    87: /*
1.12      rtr        88:  * Abstract thread interface for thread-safe libraries.  These routines
1.10      nathanw    89:  * will use stubs in libc if the application is not linked against the
                     90:  * pthread library, and the real function in the pthread library if it
                     91:  * is.
                     92:  */
                     93:
                     94: #include <pthread.h>
                     95: #include <signal.h>
                     96:
                     97: #define        mutex_t                 pthread_mutex_t
                     98: #define        MUTEX_INITIALIZER       PTHREAD_MUTEX_INITIALIZER
                     99:
                    100: #define        mutexattr_t             pthread_mutexattr_t
                    101:
                    102: #define        MUTEX_TYPE_NORMAL       PTHREAD_MUTEX_NORMAL
                    103: #define        MUTEX_TYPE_ERRORCHECK   PTHREAD_MUTEX_ERRORCHECK
                    104: #define        MUTEX_TYPE_RECURSIVE    PTHREAD_MUTEX_RECURSIVE
                    105:
                    106: #define        cond_t                  pthread_cond_t
                    107: #define        COND_INITIALIZER        PTHREAD_COND_INITIALIZER
                    108:
                    109: #define        condattr_t              pthread_condattr_t
                    110:
                    111: #define        rwlock_t                pthread_rwlock_t
                    112: #define        RWLOCK_INITIALIZER      PTHREAD_RWLOCK_INITIALIZER
                    113:
                    114: #define        rwlockattr_t            pthread_rwlockattr_t
                    115:
                    116: #define        thread_key_t            pthread_key_t
                    117:
                    118: #define        thr_t                   pthread_t
                    119:
                    120: #define        thrattr_t               pthread_attr_t
                    121:
                    122: #define        once_t                  pthread_once_t
                    123: #define        ONCE_INITIALIZER        PTHREAD_ONCE_INIT
                    124:
1.15      joerg     125: #ifdef _REENTRANT
                    126:
1.10      nathanw   127: #ifndef __LIBC_THREAD_STUBS
                    128:
                    129: __BEGIN_DECLS
                    130: int    __libc_mutex_init(mutex_t *, const mutexattr_t *);
                    131: int    __libc_mutex_lock(mutex_t *);
                    132: int    __libc_mutex_trylock(mutex_t *);
                    133: int    __libc_mutex_unlock(mutex_t *);
                    134: int    __libc_mutex_destroy(mutex_t *);
                    135:
                    136: int    __libc_mutexattr_init(mutexattr_t *);
                    137: int    __libc_mutexattr_settype(mutexattr_t *, int);
                    138: int    __libc_mutexattr_destroy(mutexattr_t *);
                    139: __END_DECLS
                    140:
                    141: #define        mutex_init(m, a)        __libc_mutex_init((m), (a))
                    142: #define        mutex_lock(m)           __libc_mutex_lock((m))
                    143: #define        mutex_trylock(m)        __libc_mutex_trylock((m))
                    144: #define        mutex_unlock(m)         __libc_mutex_unlock((m))
                    145: #define        mutex_destroy(m)        __libc_mutex_destroy((m))
                    146:
                    147: #define        mutexattr_init(ma)      __libc_mutexattr_init((ma))
                    148: #define        mutexattr_settype(ma, t) __libc_mutexattr_settype((ma), (t))
                    149: #define        mutexattr_destroy(ma)   __libc_mutexattr_destroy((ma))
                    150:
                    151: __BEGIN_DECLS
                    152: int    __libc_cond_init(cond_t *, const condattr_t *);
                    153: int    __libc_cond_signal(cond_t *);
                    154: int    __libc_cond_broadcast(cond_t *);
                    155: int    __libc_cond_wait(cond_t *, mutex_t *);
1.14      christos  156: #ifndef __LIBC12_SOURCE__
1.10      nathanw   157: int    __libc_cond_timedwait(cond_t *, mutex_t *, const struct timespec *);
1.14      christos  158: #endif
1.10      nathanw   159: int    __libc_cond_destroy(cond_t *);
                    160: __END_DECLS
                    161:
                    162: #define        cond_init(c, t, a)      __libc_cond_init((c), (a))
                    163: #define        cond_signal(c)          __libc_cond_signal((c))
                    164: #define        cond_broadcast(c)       __libc_cond_broadcast((c))
                    165: #define        cond_wait(c, m)         __libc_cond_wait((c), (m))
                    166: #define        cond_timedwait(c, m, t) __libc_cond_timedwait((c), (m), (t))
                    167: #define        cond_destroy(c)         __libc_cond_destroy((c))
                    168:
                    169: __BEGIN_DECLS
                    170: int    __libc_rwlock_init(rwlock_t *, const rwlockattr_t *);
                    171: int    __libc_rwlock_rdlock(rwlock_t *);
                    172: int    __libc_rwlock_wrlock(rwlock_t *);
                    173: int    __libc_rwlock_tryrdlock(rwlock_t *);
                    174: int    __libc_rwlock_trywrlock(rwlock_t *);
                    175: int    __libc_rwlock_unlock(rwlock_t *);
                    176: int    __libc_rwlock_destroy(rwlock_t *);
                    177: __END_DECLS
                    178:
                    179: #define        rwlock_init(l, a)       __libc_rwlock_init((l), (a))
                    180: #define        rwlock_rdlock(l)        __libc_rwlock_rdlock((l))
                    181: #define        rwlock_wrlock(l)        __libc_rwlock_wrlock((l))
                    182: #define        rwlock_tryrdlock(l)     __libc_rwlock_tryrdlock((l))
                    183: #define        rwlock_trywrlock(l)     __libc_rwlock_trywrlock((l))
                    184: #define        rwlock_unlock(l)        __libc_rwlock_unlock((l))
                    185: #define        rwlock_destroy(l)       __libc_rwlock_destroy((l))
                    186:
                    187: __BEGIN_DECLS
                    188: int    __libc_thr_keycreate(thread_key_t *, void (*)(void *));
                    189: int    __libc_thr_setspecific(thread_key_t, const void *);
                    190: void   *__libc_thr_getspecific(thread_key_t);
                    191: int    __libc_thr_keydelete(thread_key_t);
                    192: __END_DECLS
                    193:
                    194: #define        thr_keycreate(k, d)     __libc_thr_keycreate((k), (d))
                    195: #define        thr_setspecific(k, p)   __libc_thr_setspecific((k), (p))
                    196: #define        thr_getspecific(k)      __libc_thr_getspecific((k))
                    197: #define        thr_keydelete(k)        __libc_thr_keydelete((k))
                    198:
                    199: __BEGIN_DECLS
                    200: int    __libc_thr_once(once_t *, void (*)(void));
                    201: int    __libc_thr_sigsetmask(int, const sigset_t *, sigset_t *);
                    202: thr_t  __libc_thr_self(void);
                    203: int    __libc_thr_yield(void);
                    204: void   __libc_thr_create(thr_t *, const thrattr_t *,
                    205:            void *(*)(void *), void *);
                    206: void   __libc_thr_exit(void *) __attribute__((__noreturn__));
                    207: int    *__libc_thr_errno(void);
                    208: int    __libc_thr_setcancelstate(int, int *);
1.11      ad        209: unsigned int   __libc_thr_curcpu(void);
1.10      nathanw   210:
                    211: extern int __isthreaded;
                    212: __END_DECLS
                    213:
                    214: #define        thr_once(o, f)          __libc_thr_once((o), (f))
                    215: #define        thr_sigsetmask(f, n, o) __libc_thr_sigsetmask((f), (n), (o))
                    216: #define        thr_self()              __libc_thr_self()
                    217: #define        thr_yield()             __libc_thr_yield()
                    218: #define        thr_create(tp, ta, f, a) __libc_thr_create((tp), (ta), (f), (a))
                    219: #define        thr_exit(v)             __libc_thr_exit((v))
                    220: #define        thr_errno()             __libc_thr_errno()
                    221: #define        thr_enabled()           (__isthreaded)
                    222: #define thr_setcancelstate(n, o) __libc_thr_setcancelstate((n),(o))
1.11      ad        223: #define thr_curcpu()           __libc_thr_curcpu()
1.16    ! christos  224:
        !           225: #else /* __LIBC_THREAD_STUBS */
        !           226:
        !           227: __BEGIN_DECLS
        !           228: void   __libc_thr_init_stub(void);
        !           229:
        !           230: int    __libc_mutex_init_stub(mutex_t *, const mutexattr_t *);
        !           231: int    __libc_mutex_lock_stub(mutex_t *);
        !           232: int    __libc_mutex_trylock_stub(mutex_t *);
        !           233: int    __libc_mutex_unlock_stub(mutex_t *);
        !           234: int    __libc_mutex_destroy_stub(mutex_t *);
        !           235:
        !           236: int    __libc_mutexattr_init_stub(mutexattr_t *);
        !           237: int    __libc_mutexattr_destroy_stub(mutexattr_t *);
        !           238: int    __libc_mutexattr_settype_stub(mutexattr_t *, int);
        !           239:
        !           240: int    __libc_cond_init_stub(cond_t *, const condattr_t *);
        !           241: int    __libc_cond_signal_stub(cond_t *);
        !           242: int    __libc_cond_broadcast_stub(cond_t *);
        !           243: int    __libc_cond_wait_stub(cond_t *, mutex_t *);
        !           244: int    __libc_cond_timedwait_stub(cond_t *, mutex_t *,
        !           245:                                   const struct timespec *);
        !           246: int    __libc_cond_destroy_stub(cond_t *);
        !           247:
        !           248: int    __libc_rwlock_init_stub(rwlock_t *, const rwlockattr_t *);
        !           249: int    __libc_rwlock_rdlock_stub(rwlock_t *);
        !           250: int    __libc_rwlock_wrlock_stub(rwlock_t *);
        !           251: int    __libc_rwlock_tryrdlock_stub(rwlock_t *);
        !           252: int    __libc_rwlock_trywrlock_stub(rwlock_t *);
        !           253: int    __libc_rwlock_unlock_stub(rwlock_t *);
        !           254: int    __libc_rwlock_destroy_stub(rwlock_t *);
        !           255:
        !           256: int    __libc_thr_keycreate_stub(thread_key_t *, void (*)(void *));
        !           257: int    __libc_thr_setspecific_stub(thread_key_t, const void *);
        !           258: void   *__libc_thr_getspecific_stub(thread_key_t);
        !           259: int    __libc_thr_keydelete_stub(thread_key_t);
        !           260:
        !           261: int    __libc_thr_once_stub(once_t *, void (*)(void));
        !           262: int    __libc_thr_sigsetmask_stub(int, const sigset_t *, sigset_t *);
        !           263: thr_t  __libc_thr_self_stub(void);
        !           264: int    __libc_thr_yield_stub(void);
        !           265: int    __libc_thr_create_stub(thr_t *, const thrattr_t *,
        !           266:            void *(*)(void *), void *);
        !           267: void   __libc_thr_exit_stub(void *);
        !           268: int    *__libc_thr_errno_stub(void);
        !           269: int    __libc_thr_setcancelstate_stub(int, int *);
        !           270: int    __libc_thr_equal_stub(pthread_t, pthread_t);
        !           271: unsigned int   __libc_thr_curcpu_stub(void);
        !           272: __END_DECLS
        !           273:
1.10      nathanw   274: #endif /* __LIBC_THREAD_STUBS */
1.7       thorpej   275:
1.9       nathanw   276: #define        FLOCKFILE(fp)           __flockfile_internal(fp, 1)
                    277: #define        FUNLOCKFILE(fp)         __funlockfile_internal(fp, 1)
1.7       thorpej   278:
                    279: #else /* _REENTRANT */
                    280:
                    281: #define        mutex_init(m, a)
                    282: #define        mutex_lock(m)
                    283: #define        mutex_trylock(m)
                    284: #define        mutex_unlock(m)
                    285: #define        mutex_destroy(m)
                    286:
                    287: #define        cond_init(c, t, a)
                    288: #define        cond_signal(c)
                    289: #define        cond_broadcast(c)
                    290: #define        cond_wait(c, m)
                    291: #define        cond_timedwait(c, m, t)
                    292: #define        cond_destroy(c)
                    293:
                    294: #define        rwlock_init(l, a)
                    295: #define        rwlock_rdlock(l)
                    296: #define        rwlock_wrlock(l)
                    297: #define        rwlock_tryrdlock(l)
                    298: #define        rwlock_trywrlock(l)
                    299: #define        rwlock_unlock(l)
                    300: #define        rwlock_destroy(l)
                    301:
                    302: #define        thr_keycreate(k, d)
                    303: #define        thr_setspecific(k, p)
                    304: #define        thr_getspecific(k)
                    305: #define        thr_keydelete(k)
                    306:
1.15      joerg     307: static inline int
                    308: thr_once(once_t *once_control, void (*routine)(void))
                    309: {
                    310:        if (__predict_false(once_control->pto_done == 0)) {
                    311:                (*routine)();
                    312:                once_control->pto_done = 1;
                    313:        }
                    314:        return 0;
                    315: }
1.7       thorpej   316: #define        thr_sigsetmask(f, n, o)
                    317: #define        thr_self()
                    318: #define        thr_errno()
1.11      ad        319: #define        thr_curcpu()            ((unsigned int)0)
1.2       jtc       320:
1.7       thorpej   321: #define        FLOCKFILE(fp)
                    322: #define        FUNLOCKFILE(fp)
1.1       jtc       323:
1.7       thorpej   324: #endif /* _REENTRANT */

CVSweb <webmaster@jp.NetBSD.org>