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

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

1.9     ! jmc         1: /*     $OpenBSD: tib.h,v 1.8 2020/07/14 16:48:13 kettenis 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
1.9     ! jmc        57:  *             On TLS variant 2 archs, what alignment is sufficient
1.1       guenther   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:
1.4       visa       87: /* All archs but mips64 have fast TCB_GET() and don't need caching */
                     88: #ifndef        __mips64__
1.2       guenther   89: # define TCB_HAVE_MD_GET       1
1.1       guenther   90: #endif
1.2       guenther   91: #ifdef TCB_SET
                     92: # define TCB_HAVE_MD_SET       1
                     93: #else
                     94: # define TCB_SET(tcb)          __set_tcb(tcb)
1.1       guenther   95: #endif
1.3       guenther   96: #ifndef TCB_OFFSET
                     97: # define TCB_OFFSET    0
                     98: #endif
                     99:
                    100: /*
1.5       guenther  101:  * tib_cantcancel values is non-zero if the thread should skip all
1.3       guenther  102:  * cancellation processing
                    103:  */
                    104: #define CANCEL_DISABLED        1
                    105: #define CANCEL_DYING   2
                    106:
                    107: /*
                    108:  * tib_cancel_point is non-zero if we're in a cancel point; its modified
                    109:  * by the cancel point code and read by the cancellation signal handler
                    110:  */
                    111: #define CANCEL_POINT           1
                    112: #define CANCEL_POINT_DELAYED   2
1.1       guenther  113:
                    114:
                    115: #if TLS_VARIANT == 1
                    116: /*
                    117:  * ABI specifies that the static TLS data starts two words after the
                    118:  * (notional) thread pointer, with the first of those two words being
                    119:  * the TLS dtv pointer.  The other (second) word is reserved for the
1.3       guenther  120:  * implementation, so we place the pointer to the thread structure there,
                    121:  * but we place our actual thread bits before the TCB, at negative offsets
                    122:  * from the TCB pointer.  Ergo, memory is laid out, low to high, as:
1.1       guenther  123:  *
1.2       guenther  124:  *     [pthread structure]
1.1       guenther  125:  *     TIB {
1.3       guenther  126:  *             ...cancelation and other int-sized info...
1.1       guenther  127:  *             int errno
1.2       guenther  128:  *             void *locale
1.3       guenther  129:  *             TCB (- TCB_OFFSET) {
1.1       guenther  130:  *                     void *dtv
1.2       guenther  131:  *                     struct pthread *thread
1.1       guenther  132:  *             }
                    133:  *     }
                    134:  *     static TLS data
                    135:  */
                    136:
                    137: struct tib {
1.6       kettenis  138:        void    *tib_atexit;
1.3       guenther  139:        int     tib_thread_flags;       /* internal to libpthread */
                    140:        pid_t   tib_tid;
                    141:        int     tib_cantcancel;
                    142:        int     tib_cancel_point;
                    143:        int     tib_canceled;
1.1       guenther  144:        int     tib_errno;
1.2       guenther  145:        void    *tib_locale;
1.8       kettenis  146: #ifdef __powerpc64__
                    147:        void    *tib_thread;
                    148:        void    *tib_dtv;               /* internal to the runtime linker */
                    149: #else
1.1       guenther  150:        void    *tib_dtv;               /* internal to the runtime linker */
1.2       guenther  151:        void    *tib_thread;
1.8       kettenis  152: #endif
1.1       guenther  153: };
                    154:
                    155:
                    156: #elif TLS_VARIANT == 2
                    157: /*
                    158:  * ABI specifies that the static TLS data occupies the memory before
                    159:  * the TCB pointer, at negative offsets, and that on i386 and amd64
                    160:  * the word the TCB points to contains a pointer to itself.  So,
                    161:  * we place errno and our thread bits after that.  Memory is laid
                    162:  * out, low to high, as:
                    163:  *     static TLS data
                    164:  *     TIB {
1.3       guenther  165:  *             TCB (- TCB_OFFSET) {
1.1       guenther  166:  *                     self pointer [i386/amd64 only]
                    167:  *                     void *dtv
                    168:  *             }
1.2       guenther  169:  *             struct pthread *thread
1.1       guenther  170:  *             void *locale
                    171:  *             int errno
1.3       guenther  172:  *             ...cancelation and other int-sized info...
1.1       guenther  173:  *     }
1.2       guenther  174:  *     [pthread structure]
1.1       guenther  175:  */
                    176:
                    177: struct tib {
                    178: #if defined(__i386) || defined(__amd64)
                    179:        struct  tib *__tib_self;
1.2       guenther  180: # define __tib_tcb __tib_self
1.1       guenther  181: #endif
                    182:        void    *tib_dtv;               /* internal to the runtime linker */
1.2       guenther  183:        void    *tib_thread;
1.1       guenther  184:        void    *tib_locale;
                    185:        int     tib_errno;
1.3       guenther  186:        int     tib_canceled;
                    187:        int     tib_cancel_point;
                    188:        int     tib_cantcancel;
                    189:        pid_t   tib_tid;
                    190:        int     tib_thread_flags;       /* internal to libpthread */
1.6       kettenis  191:        void    *tib_atexit;
1.1       guenther  192: };
                    193:
1.2       guenther  194: #if defined(__i386) || defined(__amd64)
                    195: # define _TIB_PREP(tib)        \
1.3       guenther  196:        ((void)((tib)->__tib_self = (tib)))
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.6       kettenis  212:                (tib)->tib_atexit       = NULL;         \
1.1       guenther  213:                (tib)->tib_locale       = NULL;         \
1.3       guenther  214:                (tib)->tib_cantcancel   = 0;            \
                    215:                (tib)->tib_cancel_point = 0;            \
                    216:                (tib)->tib_canceled     = 0;            \
1.1       guenther  217:                (tib)->tib_dtv          = (dtv);        \
                    218:                (tib)->tib_errno        = 0;            \
                    219:                _TIB_PREP(tib);                         \
                    220:        } while (0)
                    221:
                    222: #ifndef        __tib_tcb
1.2       guenther  223: # define __tib_tcb             tib_dtv
1.1       guenther  224: #endif
1.3       guenther  225: #define        _TIBO_TCB               (offsetof(struct tib, __tib_tcb) + TCB_OFFSET)
1.1       guenther  226:
                    227: #define        TCB_TO_TIB(tcb)         ((struct tib *)((char *)(tcb) - _TIBO_TCB))
                    228: #define        TIB_TO_TCB(tib)         ((char *)(tib) + _TIBO_TCB)
                    229: #define        TIB_GET()               TCB_TO_TIB(TCB_GET())
                    230:
                    231:
                    232: __BEGIN_DECLS
1.7       guenther  233: struct dl_info;
                    234: struct dl_phdr_info;
                    235: struct dl_cb_0 {
                    236:        void    *(*dl_allocate_tib)(size_t);
                    237:        void     (*dl_free_tib)(void *, size_t);
                    238:        void     (*dl_clean_boot)(void);
                    239:        void    *(*dlopen)(const char *, int);
                    240:        int      (*dlclose)(void *);
                    241:        void    *(*dlsym)(void *, const char *);
                    242:        int      (*dladdr)(const void *, struct dl_info *);
                    243:        int      (*dlctl)(void *, int, void *);
                    244:        char    *(*dlerror)(void);
                    245:        int      (*dl_iterate_phdr)(int (*)(struct dl_phdr_info *,
                    246:                    size_t, void *), void *);
                    247: };
                    248:
                    249: #define        DL_CB_CUR       0
                    250: typedef        struct dl_cb_0  dl_cb;
                    251:
                    252: /* type of function passed to init functions that returns a dl_cb */
                    253: typedef        const void *dl_cb_cb(int _version);
                    254:
1.2       guenther  255: void   *_dl_allocate_tib(size_t _extra) __dso_public;
1.1       guenther  256: void   _dl_free_tib(void *_tib, size_t _extra) __dso_public;
                    257:
                    258: /* The actual syscalls */
                    259: void   *__get_tcb(void);
                    260: void   __set_tcb(void *_tcb);
                    261: __END_DECLS
                    262:
                    263: #endif /* _TIB_H_ */