[BACK]Return to tib.h CVS log [TXT][DIR] Up to [local] / src / include

Annotation of src/include/tib.h, Revision 1.3

1.3     ! guenther    1: /*     $OpenBSD: tib.h,v 1.2 2016/03/20 02:30:28 guenther Exp $        */
1.1       guenther    2: /*
                      3:  * Copyright (c) 2011,2014 Philip Guenther <guenther@openbsd.org>
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     16:  */
                     17:
                     18: /*
                     19:  * Thread Information Block (TIB) and Thread Local Storage (TLS) handling
                     20:  * (the TCB, Thread Control Block, is part of the TIB)
                     21:  */
                     22:
                     23: #ifndef        _TIB_H_
                     24: #define        _TIB_H_
                     25:
                     26: #include <sys/types.h>
                     27: #include <machine/tcb.h>
                     28:
                     29: #include <stddef.h>
                     30:
                     31:
                     32: /*
                     33:  * This header defines struct tib and at least eight macros:
                     34:  *     TLS_VARIANT
                     35:  *             Either 1 or 2  (Actually defined by <machine/tcb.h>)
                     36:  *
                     37:  *     TCB_SET(tcb)
                     38:  *             Set the TCB pointer for this thread to 'tcb'
                     39:  *
                     40:  *     TCB_GET()
                     41:  *             Return the TCB pointer for this thread
                     42:  *
                     43:  *     TCB_TO_TIB(tcb)
                     44:  *             Given a TCB pointer, return the matching TIB pointer
                     45:  *
                     46:  *     TIB_TO_TCB(tib)
                     47:  *             Given a TIB pointer, return the matching TCB pointer
                     48:  *
1.3     ! guenther   49:  *     TIB_INIT(tib, dtv, thread)
1.1       guenther   50:  *             Initializes a TIB for a new thread, using the supplied
1.3     ! guenther   51:  *             values for its dtv and thread pointers
1.1       guenther   52:  *
                     53:  *     TIB_GET()
                     54:  *             Short-hand for TCB_TO_TIB(TCB_GET())
                     55:  *
                     56:  *     TIB_EXTRA_ALIGN
                     57:  *             On TLS varaint 2 archs, what alignment is sufficient
                     58:  *             for the extra space that will be used for struct pthread?
                     59:  *
                     60:  * The following functions are provided by either ld.so (dynamic) or
                     61:  * libc (static) for allocating and freeing a common memory block that
                     62:  * will hold both the TIB and the pthread structure:
1.3     ! guenther   63:  *     _dl_allocate_tib(sizeof(struct pthread))
1.1       guenther   64:  *             Allocates a combined TIB and pthread memory region.
1.3     ! guenther   65:  *             The argument is the amount of space to reserve
        !            66:  *             for the pthread structure.  Returns a pointer to
        !            67:  *             the TIB inside the allocated block.
1.1       guenther   68:  *
                     69:  *     _dl_free_tib(tib, sizeof(struct pthread))
                     70:  *             Frees a TIB and pthread block previously allocated
1.3     ! guenther   71:  *             with _dl_allocate_tib().  Must be passed the return
1.1       guenther   72:  *             value of that previous call.
                     73:  */
                     74:
                     75: /*
                     76:  * Regarding <machine/tcb.h>:
                     77:  *  - it must define the TLS_VARIANT macro
1.3     ! guenther   78:  *  - it may define TCB_OFFSET if the TCB address in the kernel and/or
        !            79:  *    register is offset from the actual TCB address.  TCB_OFFSET > 0
        !            80:  *    means the kernel/register points to *after* the real data.
1.1       guenther   81:  *  - if there's a faster way to get or set the TCB pointer for the thread
                     82:  *    than the __{get,set}_tcb() syscalls, it should define either or both
                     83:  *    the TCB_{GET,SET} macros to do so.
                     84:  */
                     85:
                     86:
                     87: /* If <machine/tcb.h> doesn't provide a better way, then use the default */
1.2       guenther   88: #ifdef TCB_GET
                     89: # define TCB_HAVE_MD_GET       1
                     90: #else
                     91: # define TCB_GET()             __get_tcb()
1.1       guenther   92: #endif
1.2       guenther   93: #ifdef TCB_SET
                     94: # define TCB_HAVE_MD_SET       1
                     95: #else
                     96: # define TCB_SET(tcb)          __set_tcb(tcb)
1.1       guenther   97: #endif
1.3     ! guenther   98: #ifndef TCB_OFFSET
        !            99: # define TCB_OFFSET    0
        !           100: #endif
        !           101:
        !           102: /*
        !           103:  * tib_cantcancel values is non-zero is the thread should skip all
        !           104:  * cancellation processing
        !           105:  */
        !           106: #define CANCEL_DISABLED        1
        !           107: #define CANCEL_DYING   2
        !           108:
        !           109: /*
        !           110:  * tib_cancel_point is non-zero if we're in a cancel point; its modified
        !           111:  * by the cancel point code and read by the cancellation signal handler
        !           112:  */
        !           113: #define CANCEL_POINT           1
        !           114: #define CANCEL_POINT_DELAYED   2
1.1       guenther  115:
                    116:
                    117: #if TLS_VARIANT == 1
                    118: /*
                    119:  * ABI specifies that the static TLS data starts two words after the
                    120:  * (notional) thread pointer, with the first of those two words being
                    121:  * the TLS dtv pointer.  The other (second) word is reserved for the
1.3     ! guenther  122:  * implementation, so we place the pointer to the thread structure there,
        !           123:  * but we place our actual thread bits before the TCB, at negative offsets
        !           124:  * from the TCB pointer.  Ergo, memory is laid out, low to high, as:
1.1       guenther  125:  *
1.2       guenther  126:  *     [pthread structure]
1.1       guenther  127:  *     TIB {
1.3     ! guenther  128:  *             ...cancelation and other int-sized info...
1.1       guenther  129:  *             int errno
1.2       guenther  130:  *             void *locale
1.3     ! guenther  131:  *             TCB (- TCB_OFFSET) {
1.1       guenther  132:  *                     void *dtv
1.2       guenther  133:  *                     struct pthread *thread
1.1       guenther  134:  *             }
                    135:  *     }
                    136:  *     static TLS data
                    137:  */
                    138:
                    139: struct tib {
1.3     ! guenther  140:        int     tib_thread_flags;       /* internal to libpthread */
        !           141:        pid_t   tib_tid;
        !           142:        int     tib_cantcancel;
        !           143:        int     tib_cancel_point;
        !           144:        int     tib_canceled;
1.1       guenther  145:        int     tib_errno;
1.2       guenther  146:        void    *tib_locale;
1.1       guenther  147:        void    *tib_dtv;               /* internal to the runtime linker */
1.2       guenther  148:        void    *tib_thread;
1.1       guenther  149: };
                    150:
                    151:
                    152: #elif TLS_VARIANT == 2
                    153: /*
                    154:  * ABI specifies that the static TLS data occupies the memory before
                    155:  * the TCB pointer, at negative offsets, and that on i386 and amd64
                    156:  * the word the TCB points to contains a pointer to itself.  So,
                    157:  * we place errno and our thread bits after that.  Memory is laid
                    158:  * out, low to high, as:
                    159:  *     static TLS data
                    160:  *     TIB {
1.3     ! guenther  161:  *             TCB (- TCB_OFFSET) {
1.1       guenther  162:  *                     self pointer [i386/amd64 only]
                    163:  *                     void *dtv
                    164:  *             }
1.2       guenther  165:  *             struct pthread *thread
1.1       guenther  166:  *             void *locale
                    167:  *             int errno
1.3     ! guenther  168:  *             ...cancelation and other int-sized info...
1.1       guenther  169:  *     }
1.2       guenther  170:  *     [pthread structure]
1.1       guenther  171:  */
                    172:
                    173: struct tib {
                    174: #if defined(__i386) || defined(__amd64)
                    175:        struct  tib *__tib_self;
1.2       guenther  176: # define __tib_tcb __tib_self
1.1       guenther  177: #endif
                    178:        void    *tib_dtv;               /* internal to the runtime linker */
1.2       guenther  179:        void    *tib_thread;
1.1       guenther  180:        void    *tib_locale;
                    181:        int     tib_errno;
1.3     ! guenther  182:        int     tib_canceled;
        !           183:        int     tib_cancel_point;
        !           184:        int     tib_cantcancel;
        !           185:        pid_t   tib_tid;
        !           186:        int     tib_thread_flags;       /* internal to libpthread */
        !           187: #if !defined(__LP64__) && !defined(__i386)
1.1       guenther  188:        int     __tib_padding;          /* padding for 8byte alignment */
                    189: #endif
                    190: };
                    191:
1.2       guenther  192: #if defined(__i386) || defined(__amd64)
                    193: # define _TIB_PREP(tib)        \
1.3     ! guenther  194:        ((void)((tib)->__tib_self = (tib)))
        !           195: #elif !defined(__LP64__) && !defined(__i386)
1.2       guenther  196: # define _TIB_PREP(tib)        ((void)((tib)->__tib_padding = 0))
1.1       guenther  197: #endif
                    198:
                    199: #define        TIB_EXTRA_ALIGN         sizeof(void *)
                    200:
                    201: #else
                    202: # error "unknown TLS variant"
                    203: #endif
                    204:
                    205: /* nothing to do by default */
                    206: #ifndef        _TIB_PREP
1.2       guenther  207: # define _TIB_PREP(tib)        ((void)0)
1.1       guenther  208: #endif
                    209:
1.2       guenther  210: #define        TIB_INIT(tib, dtv, thread)      do {            \
                    211:                (tib)->tib_thread       = (thread);     \
1.1       guenther  212:                (tib)->tib_locale       = NULL;         \
1.3     ! guenther  213:                (tib)->tib_cantcancel   = 0;            \
        !           214:                (tib)->tib_cancel_point = 0;            \
        !           215:                (tib)->tib_canceled     = 0;            \
1.1       guenther  216:                (tib)->tib_dtv          = (dtv);        \
                    217:                (tib)->tib_errno        = 0;            \
                    218:                _TIB_PREP(tib);                         \
                    219:        } while (0)
                    220:
                    221: #ifndef        __tib_tcb
1.2       guenther  222: # define __tib_tcb             tib_dtv
1.1       guenther  223: #endif
1.3     ! guenther  224: #define        _TIBO_TCB               (offsetof(struct tib, __tib_tcb) + TCB_OFFSET)
1.1       guenther  225:
                    226: #define        TCB_TO_TIB(tcb)         ((struct tib *)((char *)(tcb) - _TIBO_TCB))
                    227: #define        TIB_TO_TCB(tib)         ((char *)(tib) + _TIBO_TCB)
                    228: #define        TIB_GET()               TCB_TO_TIB(TCB_GET())
                    229:
                    230:
                    231: __BEGIN_DECLS
1.2       guenther  232: void   *_dl_allocate_tib(size_t _extra) __dso_public;
1.1       guenther  233: void   _dl_free_tib(void *_tib, size_t _extra) __dso_public;
                    234:
                    235: /* The actual syscalls */
                    236: void   *__get_tcb(void);
                    237: void   __set_tcb(void *_tcb);
                    238: __END_DECLS
                    239:
                    240: #endif /* _TIB_H_ */