Source code pulled from OpenBSD for OpenNTPD. The place to contribute to this code is via the OpenBSD CVS tree.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

235 lines
6.5 KiB

  1. /* $OpenBSD: tib.h,v 1.2 2016/03/20 02:30:28 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. * Thread Information Block (TIB) and Thread Local Storage (TLS) handling
  19. * (the TCB, Thread Control Block, is part of the TIB)
  20. */
  21. #ifndef _TIB_H_
  22. #define _TIB_H_
  23. #include <sys/types.h>
  24. #include <machine/tcb.h>
  25. #include <stddef.h>
  26. /*
  27. * This header defines struct tib and at least eight macros:
  28. * TLS_VARIANT
  29. * Either 1 or 2 (Actually defined by <machine/tcb.h>)
  30. *
  31. * TCB_SET(tcb)
  32. * Set the TCB pointer for this thread to 'tcb'
  33. *
  34. * TCB_GET()
  35. * Return the TCB pointer for this thread
  36. *
  37. * TCB_TO_TIB(tcb)
  38. * Given a TCB pointer, return the matching TIB pointer
  39. *
  40. * TIB_TO_TCB(tib)
  41. * Given a TIB pointer, return the matching TCB pointer
  42. *
  43. * TIB_INIT(tib, dtv)
  44. * Initializes a TIB for a new thread, using the supplied
  45. * value for the dtv pointer
  46. *
  47. * TIB_TO_THREAD(tib)
  48. * Given a TIB pointer, return a pointer to the struct pthread
  49. *
  50. * TIB_GET()
  51. * Short-hand for TCB_TO_TIB(TCB_GET())
  52. *
  53. * TIB_THREAD()
  54. * Returns a pointer to this thread's struct pthread
  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:
  63. * _dl_allocate_tib(sizeof(struct pthread), flags)
  64. * Allocates a combined TIB and pthread memory region.
  65. * The first argument is the amount of space to reserve
  66. * for the pthread structure; the second argument is
  67. * either zero or DAT_UPDATE_CURRENT, the latter meaning
  68. * this call is to update/replace the current thread's
  69. * TIB. Returns a pointer to the TIB inside the
  70. * allocated block.
  71. *
  72. * _dl_free_tib(tib, sizeof(struct pthread))
  73. * Frees a TIB and pthread block previously allocated
  74. * with _dl_allocate_tls(). Must be passed the return
  75. * value of that previous call.
  76. */
  77. /*
  78. * Regarding <machine/tcb.h>:
  79. * - it must define the TLS_VARIANT macro
  80. * - if there's a faster way to get or set the TCB pointer for the thread
  81. * than the __{get,set}_tcb() syscalls, it should define either or both
  82. * the TCB_{GET,SET} macros to do so.
  83. */
  84. /* If <machine/tcb.h> doesn't provide a better way, then use the default */
  85. #ifdef TCB_GET
  86. # define TCB_HAVE_MD_GET 1
  87. #else
  88. # define TCB_GET() __get_tcb()
  89. #endif
  90. #ifdef TCB_SET
  91. # define TCB_HAVE_MD_SET 1
  92. #else
  93. # define TCB_SET(tcb) __set_tcb(tcb)
  94. #endif
  95. #if TLS_VARIANT == 1
  96. /*
  97. * ABI specifies that the static TLS data starts two words after the
  98. * (notional) thread pointer, with the first of those two words being
  99. * the TLS dtv pointer. The other (second) word is reserved for the
  100. * implementation, so we place the thread's locale there, but we place
  101. * our thread bits before the TCB, at negative offsets from the
  102. * TCB pointer. Ergo, memory is laid out, low to high, as:
  103. *
  104. * [pthread structure]
  105. * TIB {
  106. * int cancel_flags
  107. * int cancel_requested
  108. * int errno
  109. * void *locale
  110. * TCB {
  111. * void *dtv
  112. * struct pthread *thread
  113. * }
  114. * }
  115. * static TLS data
  116. */
  117. struct tib {
  118. #ifdef __LP64__
  119. int __tib_padding; /* padding for 8byte alignment */
  120. #endif
  121. int tib_cancel_flags;
  122. int tib_cancel;
  123. int tib_errno;
  124. void *tib_locale;
  125. void *tib_dtv; /* internal to the runtime linker */
  126. void *tib_thread;
  127. };
  128. #ifdef __LP64__
  129. # define _TIB_PREP(tib) ((void)((tib)->__tib_padding = 0))
  130. #endif
  131. #define _TIBO_PTHREAD (- _ALIGN(sizeof(struct pthread)))
  132. #elif TLS_VARIANT == 2
  133. /*
  134. * ABI specifies that the static TLS data occupies the memory before
  135. * the TCB pointer, at negative offsets, and that on i386 and amd64
  136. * the word the TCB points to contains a pointer to itself. So,
  137. * we place errno and our thread bits after that. Memory is laid
  138. * out, low to high, as:
  139. * static TLS data
  140. * TIB {
  141. * TCB {
  142. * self pointer [i386/amd64 only]
  143. * void *dtv
  144. * }
  145. * struct pthread *thread
  146. * void *locale
  147. * int errno
  148. * int cancel_count_flags
  149. * int cancel_requested
  150. * }
  151. * [pthread structure]
  152. */
  153. struct tib {
  154. #if defined(__i386) || defined(__amd64)
  155. struct tib *__tib_self;
  156. # define __tib_tcb __tib_self
  157. #endif
  158. void *tib_dtv; /* internal to the runtime linker */
  159. void *tib_thread;
  160. void *tib_locale;
  161. int tib_errno;
  162. int tib_cancel; /* set to request cancelation */
  163. int tib_cancel_flags;
  164. #if defined(__LP64__) || defined(__i386)
  165. int __tib_padding; /* padding for 8byte alignment */
  166. #endif
  167. };
  168. #define _TIBO_PTHREAD _ALIGN(sizeof(struct tib))
  169. #if defined(__i386) || defined(__amd64)
  170. # define _TIB_PREP(tib) \
  171. ((void)((tib)->__tib_self = (tib), (tib)->__tib_padding = 0))
  172. #elif defined(__LP64__)
  173. # define _TIB_PREP(tib) ((void)((tib)->__tib_padding = 0))
  174. #endif
  175. #define TIB_EXTRA_ALIGN sizeof(void *)
  176. #else
  177. # error "unknown TLS variant"
  178. #endif
  179. /* nothing to do by default */
  180. #ifndef _TIB_PREP
  181. # define _TIB_PREP(tib) ((void)0)
  182. #endif
  183. #define TIB_INIT(tib, dtv, thread) do { \
  184. (tib)->tib_thread = (thread); \
  185. (tib)->tib_locale = NULL; \
  186. (tib)->tib_cancel_flags = 0; \
  187. (tib)->tib_cancel = 0; \
  188. (tib)->tib_dtv = (dtv); \
  189. (tib)->tib_errno = 0; \
  190. _TIB_PREP(tib); \
  191. } while (0)
  192. #ifndef __tib_tcb
  193. # define __tib_tcb tib_dtv
  194. #endif
  195. #define _TIBO_TCB offsetof(struct tib, __tib_tcb)
  196. #define TCB_TO_TIB(tcb) ((struct tib *)((char *)(tcb) - _TIBO_TCB))
  197. #define TIB_TO_TCB(tib) ((char *)(tib) + _TIBO_TCB)
  198. #define TIB_TO_THREAD(tib) ((struct pthread *)(tib)->tib_thread)
  199. #define TIB_GET() TCB_TO_TIB(TCB_GET())
  200. #define TCB_THREAD() TIB_TO_THREAD(TIB_GET())
  201. __BEGIN_DECLS
  202. void *_dl_allocate_tib(size_t _extra) __dso_public;
  203. void _dl_free_tib(void *_tib, size_t _extra) __dso_public;
  204. /* The actual syscalls */
  205. void *__get_tcb(void);
  206. void __set_tcb(void *_tcb);
  207. __END_DECLS
  208. #endif /* _TIB_H_ */