version 1.2, 2016/03/20 02:30:28 |
version 1.3, 2016/05/07 19:05:21 |
|
|
* TIB_TO_TCB(tib) |
* TIB_TO_TCB(tib) |
* Given a TIB pointer, return the matching TCB pointer |
* Given a TIB pointer, return the matching TCB pointer |
* |
* |
* TIB_INIT(tib, dtv) |
* TIB_INIT(tib, dtv, thread) |
* Initializes a TIB for a new thread, using the supplied |
* Initializes a TIB for a new thread, using the supplied |
* value for the dtv pointer |
* values for its dtv and thread pointers |
* |
* |
* TIB_TO_THREAD(tib) |
|
* Given a TIB pointer, return a pointer to the struct pthread |
|
* |
|
* TIB_GET() |
* TIB_GET() |
* Short-hand for TCB_TO_TIB(TCB_GET()) |
* Short-hand for TCB_TO_TIB(TCB_GET()) |
* |
* |
* TIB_THREAD() |
|
* Returns a pointer to this thread's struct pthread |
|
* |
|
* TIB_EXTRA_ALIGN |
* TIB_EXTRA_ALIGN |
* On TLS varaint 2 archs, what alignment is sufficient |
* On TLS varaint 2 archs, what alignment is sufficient |
* for the extra space that will be used for struct pthread? |
* for the extra space that will be used for struct pthread? |
|
|
* The following functions are provided by either ld.so (dynamic) or |
* The following functions are provided by either ld.so (dynamic) or |
* libc (static) for allocating and freeing a common memory block that |
* libc (static) for allocating and freeing a common memory block that |
* will hold both the TIB and the pthread structure: |
* will hold both the TIB and the pthread structure: |
* _dl_allocate_tib(sizeof(struct pthread), flags) |
* _dl_allocate_tib(sizeof(struct pthread)) |
* Allocates a combined TIB and pthread memory region. |
* Allocates a combined TIB and pthread memory region. |
* The first argument is the amount of space to reserve |
* The argument is the amount of space to reserve |
* for the pthread structure; the second argument is |
* for the pthread structure. Returns a pointer to |
* either zero or DAT_UPDATE_CURRENT, the latter meaning |
* the TIB inside the allocated block. |
* this call is to update/replace the current thread's |
|
* TIB. Returns a pointer to the TIB inside the |
|
* allocated block. |
|
* |
* |
* _dl_free_tib(tib, sizeof(struct pthread)) |
* _dl_free_tib(tib, sizeof(struct pthread)) |
* Frees a TIB and pthread block previously allocated |
* Frees a TIB and pthread block previously allocated |
* with _dl_allocate_tls(). Must be passed the return |
* with _dl_allocate_tib(). Must be passed the return |
* value of that previous call. |
* value of that previous call. |
*/ |
*/ |
|
|
/* |
/* |
* Regarding <machine/tcb.h>: |
* Regarding <machine/tcb.h>: |
* - it must define the TLS_VARIANT macro |
* - it must define the TLS_VARIANT macro |
|
* - it may define TCB_OFFSET if the TCB address in the kernel and/or |
|
* register is offset from the actual TCB address. TCB_OFFSET > 0 |
|
* means the kernel/register points to *after* the real data. |
* - if there's a faster way to get or set the TCB pointer for the thread |
* - if there's a faster way to get or set the TCB pointer for the thread |
* than the __{get,set}_tcb() syscalls, it should define either or both |
* than the __{get,set}_tcb() syscalls, it should define either or both |
* the TCB_{GET,SET} macros to do so. |
* the TCB_{GET,SET} macros to do so. |
|
|
#else |
#else |
# define TCB_SET(tcb) __set_tcb(tcb) |
# define TCB_SET(tcb) __set_tcb(tcb) |
#endif |
#endif |
|
#ifndef TCB_OFFSET |
|
# define TCB_OFFSET 0 |
|
#endif |
|
|
|
/* |
|
* tib_cantcancel values is non-zero is the thread should skip all |
|
* cancellation processing |
|
*/ |
|
#define CANCEL_DISABLED 1 |
|
#define CANCEL_DYING 2 |
|
|
|
/* |
|
* tib_cancel_point is non-zero if we're in a cancel point; its modified |
|
* by the cancel point code and read by the cancellation signal handler |
|
*/ |
|
#define CANCEL_POINT 1 |
|
#define CANCEL_POINT_DELAYED 2 |
|
|
|
|
#if TLS_VARIANT == 1 |
#if TLS_VARIANT == 1 |
/* |
/* |
* ABI specifies that the static TLS data starts two words after the |
* ABI specifies that the static TLS data starts two words after the |
* (notional) thread pointer, with the first of those two words being |
* (notional) thread pointer, with the first of those two words being |
* the TLS dtv pointer. The other (second) word is reserved for the |
* the TLS dtv pointer. The other (second) word is reserved for the |
* implementation, so we place the thread's locale there, but we place |
* implementation, so we place the pointer to the thread structure there, |
* our thread bits before the TCB, at negative offsets from the |
* but we place our actual thread bits before the TCB, at negative offsets |
* TCB pointer. Ergo, memory is laid out, low to high, as: |
* from the TCB pointer. Ergo, memory is laid out, low to high, as: |
* |
* |
* [pthread structure] |
* [pthread structure] |
* TIB { |
* TIB { |
* int cancel_flags |
* ...cancelation and other int-sized info... |
* int cancel_requested |
|
* int errno |
* int errno |
* void *locale |
* void *locale |
* TCB { |
* TCB (- TCB_OFFSET) { |
* void *dtv |
* void *dtv |
* struct pthread *thread |
* struct pthread *thread |
* } |
* } |
|
|
*/ |
*/ |
|
|
struct tib { |
struct tib { |
#ifdef __LP64__ |
int tib_thread_flags; /* internal to libpthread */ |
int __tib_padding; /* padding for 8byte alignment */ |
pid_t tib_tid; |
#endif |
int tib_cantcancel; |
int tib_cancel_flags; |
int tib_cancel_point; |
int tib_cancel; |
int tib_canceled; |
int tib_errno; |
int tib_errno; |
void *tib_locale; |
void *tib_locale; |
void *tib_dtv; /* internal to the runtime linker */ |
void *tib_dtv; /* internal to the runtime linker */ |
void *tib_thread; |
void *tib_thread; |
}; |
}; |
#ifdef __LP64__ |
|
# define _TIB_PREP(tib) ((void)((tib)->__tib_padding = 0)) |
|
#endif |
|
|
|
#define _TIBO_PTHREAD (- _ALIGN(sizeof(struct pthread))) |
|
|
|
#elif TLS_VARIANT == 2 |
#elif TLS_VARIANT == 2 |
/* |
/* |
|
|
* out, low to high, as: |
* out, low to high, as: |
* static TLS data |
* static TLS data |
* TIB { |
* TIB { |
* TCB { |
* TCB (- TCB_OFFSET) { |
* self pointer [i386/amd64 only] |
* self pointer [i386/amd64 only] |
* void *dtv |
* void *dtv |
* } |
* } |
* struct pthread *thread |
* struct pthread *thread |
* void *locale |
* void *locale |
* int errno |
* int errno |
* int cancel_count_flags |
* ...cancelation and other int-sized info... |
* int cancel_requested |
|
* } |
* } |
* [pthread structure] |
* [pthread structure] |
*/ |
*/ |
|
|
void *tib_thread; |
void *tib_thread; |
void *tib_locale; |
void *tib_locale; |
int tib_errno; |
int tib_errno; |
int tib_cancel; /* set to request cancelation */ |
int tib_canceled; |
int tib_cancel_flags; |
int tib_cancel_point; |
#if defined(__LP64__) || defined(__i386) |
int tib_cantcancel; |
|
pid_t tib_tid; |
|
int tib_thread_flags; /* internal to libpthread */ |
|
#if !defined(__LP64__) && !defined(__i386) |
int __tib_padding; /* padding for 8byte alignment */ |
int __tib_padding; /* padding for 8byte alignment */ |
#endif |
#endif |
}; |
}; |
|
|
#define _TIBO_PTHREAD _ALIGN(sizeof(struct tib)) |
|
|
|
#if defined(__i386) || defined(__amd64) |
#if defined(__i386) || defined(__amd64) |
# define _TIB_PREP(tib) \ |
# define _TIB_PREP(tib) \ |
((void)((tib)->__tib_self = (tib), (tib)->__tib_padding = 0)) |
((void)((tib)->__tib_self = (tib))) |
#elif defined(__LP64__) |
#elif !defined(__LP64__) && !defined(__i386) |
# define _TIB_PREP(tib) ((void)((tib)->__tib_padding = 0)) |
# define _TIB_PREP(tib) ((void)((tib)->__tib_padding = 0)) |
#endif |
#endif |
|
|
|
|
#define TIB_INIT(tib, dtv, thread) do { \ |
#define TIB_INIT(tib, dtv, thread) do { \ |
(tib)->tib_thread = (thread); \ |
(tib)->tib_thread = (thread); \ |
(tib)->tib_locale = NULL; \ |
(tib)->tib_locale = NULL; \ |
(tib)->tib_cancel_flags = 0; \ |
(tib)->tib_cantcancel = 0; \ |
(tib)->tib_cancel = 0; \ |
(tib)->tib_cancel_point = 0; \ |
|
(tib)->tib_canceled = 0; \ |
(tib)->tib_dtv = (dtv); \ |
(tib)->tib_dtv = (dtv); \ |
(tib)->tib_errno = 0; \ |
(tib)->tib_errno = 0; \ |
_TIB_PREP(tib); \ |
_TIB_PREP(tib); \ |
|
|
#ifndef __tib_tcb |
#ifndef __tib_tcb |
# define __tib_tcb tib_dtv |
# define __tib_tcb tib_dtv |
#endif |
#endif |
#define _TIBO_TCB offsetof(struct tib, __tib_tcb) |
#define _TIBO_TCB (offsetof(struct tib, __tib_tcb) + TCB_OFFSET) |
|
|
#define TCB_TO_TIB(tcb) ((struct tib *)((char *)(tcb) - _TIBO_TCB)) |
#define TCB_TO_TIB(tcb) ((struct tib *)((char *)(tcb) - _TIBO_TCB)) |
#define TIB_TO_TCB(tib) ((char *)(tib) + _TIBO_TCB) |
#define TIB_TO_TCB(tib) ((char *)(tib) + _TIBO_TCB) |
#define TIB_TO_THREAD(tib) ((struct pthread *)(tib)->tib_thread) |
|
#define TIB_GET() TCB_TO_TIB(TCB_GET()) |
#define TIB_GET() TCB_TO_TIB(TCB_GET()) |
#define TCB_THREAD() TIB_TO_THREAD(TIB_GET()) |
|
|
|
|
|
__BEGIN_DECLS |
__BEGIN_DECLS |