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

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

1.1     ! guenther    1: /*     $OpenBSD: tcb.h,v 1.5 2013/02/14 03:38:15 guenther Exp $        */
        !             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:  *
        !            49:  *     TIB_INIT(tib, dtv)
        !            50:  *             Initializes a TIB for a new thread, using the supplied
        !            51:  *             value for the dtv pointer
        !            52:  *
        !            53:  *     TIB_COPY(tib, oldtib)
        !            54:  *             Copies oldtib to tib, (re)initializing the internal members
        !            55:  *
        !            56:  *     TIB_TO_THREAD(tib)
        !            57:  *             Given a TIB pointer, return a pointer to the struct pthread
        !            58:  *
        !            59:  *     TIB_GET()
        !            60:  *             Short-hand for TCB_TO_TIB(TCB_GET())
        !            61:  *
        !            62:  *     TIB_THREAD()
        !            63:  *             Returns a pointer to this thread's struct pthread
        !            64:  *
        !            65:  *     TIB_EXTRA_ALIGN
        !            66:  *             On TLS varaint 2 archs, what alignment is sufficient
        !            67:  *             for the extra space that will be used for struct pthread?
        !            68:  *
        !            69:  * The following functions are provided by either ld.so (dynamic) or
        !            70:  * libc (static) for allocating and freeing a common memory block that
        !            71:  * will hold both the TIB and the pthread structure:
        !            72:  *     _dl_allocate_tib(sizeof(struct pthread), flags)
        !            73:  *             Allocates a combined TIB and pthread memory region.
        !            74:  *             The first argument is the amount of space to reserve
        !            75:  *             for the pthread structure; the second argument is
        !            76:  *             either zero or DAT_UPDATE_CURRENT, the latter meaning
        !            77:  *             this call is to update/replace the current thread's
        !            78:  *             TIB.  Returns a pointer to the TIB inside the
        !            79:  *             allocated block.
        !            80:  *
        !            81:  *     _dl_free_tib(tib, sizeof(struct pthread))
        !            82:  *             Frees a TIB and pthread block previously allocated
        !            83:  *             with _dl_allocate_tls().  Must be passed the return
        !            84:  *             value of that previous call.
        !            85:  */
        !            86:
        !            87: /*
        !            88:  * Regarding <machine/tcb.h>:
        !            89:  *  - it must define the TLS_VARIANT macro
        !            90:  *  - if there's a faster way to get or set the TCB pointer for the thread
        !            91:  *    than the __{get,set}_tcb() syscalls, it should define either or both
        !            92:  *    the TCB_{GET,SET} macros to do so.
        !            93:  */
        !            94:
        !            95:
        !            96: /* If <machine/tcb.h> doesn't provide a better way, then use the default */
        !            97: #ifndef        TCB_GET
        !            98: #define        TCB_GET()       __get_tcb()
        !            99: #endif
        !           100: #ifndef        TCB_SET
        !           101: #define        TCB_SET(tcb)    __set_tcb(tcb)
        !           102: #endif
        !           103:
        !           104:
        !           105: #if TLS_VARIANT == 1
        !           106: /*
        !           107:  * ABI specifies that the static TLS data starts two words after the
        !           108:  * (notional) thread pointer, with the first of those two words being
        !           109:  * the TLS dtv pointer.  The other (second) word is reserved for the
        !           110:  * implementation, so we place the thread's locale there, but we place
        !           111:  * our thread bits before the TCB, at negative offsets from the
        !           112:  * TCB pointer.  Ergo, memory is laid out, low to high, as:
        !           113:  *
        !           114:  *     pthread structure
        !           115:  *     TIB {
        !           116:  *             int cancel_flags
        !           117:  *             int cancel_requested
        !           118:  *             int errno
        !           119:  *             TCB {
        !           120:  *                     void *dtv
        !           121:  *                     void *locale
        !           122:  *             }
        !           123:  *     }
        !           124:  *     static TLS data
        !           125:  */
        !           126:
        !           127: struct tib {
        !           128:        int     __tib_padding           /* padding for 8byte alignment */
        !           129:        int     tib_cancel_flags;
        !           130:        int     tib_cancel;
        !           131:        int     tib_errno;
        !           132:        void    *tib_dtv;               /* internal to the runtime linker */
        !           133:        void    *tib_locale;
        !           134: };
        !           135: #define _TIB_PREP(tib) ((void)((tib)->__tib_padding = 0))
        !           136:
        !           137: #define        _TIBO_PTHREAD           (- _ALIGN(sizeof(struct pthread)))
        !           138:
        !           139: #elif TLS_VARIANT == 2
        !           140: /*
        !           141:  * ABI specifies that the static TLS data occupies the memory before
        !           142:  * the TCB pointer, at negative offsets, and that on i386 and amd64
        !           143:  * the word the TCB points to contains a pointer to itself.  So,
        !           144:  * we place errno and our thread bits after that.  Memory is laid
        !           145:  * out, low to high, as:
        !           146:  *     static TLS data
        !           147:  *     TIB {
        !           148:  *             TCB {
        !           149:  *                     self pointer [i386/amd64 only]
        !           150:  *                     void *dtv
        !           151:  *             }
        !           152:  *             void *locale
        !           153:  *             int errno
        !           154:  *             int cancel_count_flags
        !           155:  *             int cancel_requested
        !           156:  *     }
        !           157:  *     pthread structure
        !           158:  */
        !           159:
        !           160: struct tib {
        !           161: #if defined(__i386) || defined(__amd64)
        !           162:        struct  tib *__tib_self;
        !           163: #define        __tib_tcb __tib_self
        !           164: #endif
        !           165:        void    *tib_dtv;               /* internal to the runtime linker */
        !           166:        void    *tib_locale;
        !           167:        int     tib_errno;
        !           168:        int     tib_cancel;             /* set to request cancelation */
        !           169:        int     tib_cancel_flags;
        !           170: #if !defined(__i386)
        !           171:        int     __tib_padding;          /* padding for 8byte alignment */
        !           172: #endif
        !           173: };
        !           174:
        !           175: #define        _TIBO_PTHREAD           _ALIGN(sizeof(struct tib))
        !           176:
        !           177: #if defined(__i386)
        !           178: #define _TIB_PREP(tib) ((void)((tib)->__tib_self = (tib)))
        !           179: #elif defined(__amd64)
        !           180: #define _TIB_PREP(tib) \
        !           181:        ((void)((tib)->__tib_self = (tib), (tib)->__tib_padding = 0))
        !           182: #else
        !           183: #define _TIB_PREP(tib) ((void)((tib)->__tib_padding = 0))
        !           184: #endif
        !           185:
        !           186: #define        TIB_EXTRA_ALIGN         sizeof(void *)
        !           187:
        !           188: #else
        !           189: # error "unknown TLS variant"
        !           190: #endif
        !           191:
        !           192: /* nothing to do by default */
        !           193: #ifndef        _TIB_PREP
        !           194: #define        _TIB_PREP(tib)  ((void)0)
        !           195: #endif
        !           196:
        !           197: #define        TIB_INIT(tib, dtv)      do {            \
        !           198:                (tib)->tib_locale       = NULL;         \
        !           199:                (tib)->tib_cancel_flags = 0;            \
        !           200:                (tib)->tib_cancel       = 0;            \
        !           201:                (tib)->tib_dtv          = (dtv);        \
        !           202:                (tib)->tib_errno        = 0;            \
        !           203:                _TIB_PREP(tib);                         \
        !           204:        } while (0)
        !           205: #define        TIB_COPY(tib, oldtib)           do {            \
        !           206:                *(tib) = *(oldtib);                     \
        !           207:                _TIB_PREP(tib);                         \
        !           208:        } while (0)
        !           209:
        !           210: #ifndef        __tib_tcb
        !           211: #define        __tib_tcb               tib_dtv
        !           212: #endif
        !           213: #define        _TIBO_TCB               offsetof(struct tib, __tib_tcb)
        !           214:
        !           215: #define        TCB_TO_TIB(tcb)         ((struct tib *)((char *)(tcb) - _TIBO_TCB))
        !           216: #define        TIB_TO_TCB(tib)         ((char *)(tib) + _TIBO_TCB)
        !           217: #define        TIB_TO_THREAD(tib)      ((struct pthread *)((char *)(tib) + \
        !           218:                                _TIBO_PTHREAD))
        !           219: #define        THREAD_TO_TIB(thread)   ((struct tib *)((char *)(thread) - \
        !           220:                                _TIBO_PTHREAD))
        !           221: #define        TIB_GET()               TCB_TO_TIB(TCB_GET())
        !           222: #define        TIB_THREAD()            TIB_TO_THREAD(TIB_GET())
        !           223:
        !           224:
        !           225: __BEGIN_DECLS
        !           226: void   *_dl_allocate_tib(size_t _extra, int _flags) __dso_public;
        !           227: #define        DAT_UPDATE_CURRENT      1
        !           228: void   _dl_free_tib(void *_tib, size_t _extra) __dso_public;
        !           229:
        !           230: /* The actual syscalls */
        !           231: void   *__get_tcb(void);
        !           232: void   __set_tcb(void *_tcb);
        !           233:
        !           234: /* The function in libc called by crt0 to init the tcb in static processes */
        !           235: void   __init_tcb(char **_envp) __dso_hidden;
        !           236: __END_DECLS
        !           237:
        !           238: #endif /* _TIB_H_ */