thread_local_alloc.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * Copyright (c) 2000-2005 by Hewlett-Packard Company. All rights reserved.
  3. *
  4. * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
  5. * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
  6. *
  7. * Permission is hereby granted to use or copy this program
  8. * for any purpose, provided the above notices are retained on all copies.
  9. * Permission to modify the code and to distribute modified code is granted,
  10. * provided the above notices are retained, and a notice that the code was
  11. * modified is included with the above copyright notice.
  12. */
  13. /* Included indirectly from a thread-library-specific file. */
  14. /* This is the interface for thread-local allocation, whose */
  15. /* implementation is mostly thread-library-independent. */
  16. /* Here we describe only the interface that needs to be known */
  17. /* and invoked from the thread support layer; the actual */
  18. /* implementation also exports GC_malloc and friends, which */
  19. /* are declared in gc.h. */
  20. #ifndef GC_THREAD_LOCAL_ALLOC_H
  21. #define GC_THREAD_LOCAL_ALLOC_H
  22. #include "private/gc_priv.h"
  23. #ifdef THREAD_LOCAL_ALLOC
  24. #include "gc_inline.h"
  25. #if defined(USE_HPUX_TLS)
  26. # error USE_HPUX_TLS macro was replaced by USE_COMPILER_TLS
  27. #endif
  28. #include <stdlib.h>
  29. EXTERN_C_BEGIN
  30. #if !defined(USE_PTHREAD_SPECIFIC) && !defined(USE_WIN32_SPECIFIC) \
  31. && !defined(USE_WIN32_COMPILER_TLS) && !defined(USE_COMPILER_TLS) \
  32. && !defined(USE_CUSTOM_SPECIFIC)
  33. # if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32)
  34. # if defined(CYGWIN32) && GC_GNUC_PREREQ(4, 0)
  35. # if defined(__clang__)
  36. /* As of Cygwin clang3.5.2, thread-local storage is unsupported. */
  37. # define USE_PTHREAD_SPECIFIC
  38. # else
  39. # define USE_COMPILER_TLS
  40. # endif
  41. # elif defined(__GNUC__) || defined(MSWINCE)
  42. # define USE_WIN32_SPECIFIC
  43. # else
  44. # define USE_WIN32_COMPILER_TLS
  45. # endif /* !GNU */
  46. # elif (defined(LINUX) && !defined(ARM32) && !defined(AVR32) \
  47. && GC_GNUC_PREREQ(3, 3) \
  48. && !(defined(__clang__) && defined(HOST_ANDROID))) \
  49. || (defined(FREEBSD) && defined(__GLIBC__) /* kFreeBSD */ \
  50. && GC_GNUC_PREREQ(4, 4)) \
  51. || (defined(HOST_ANDROID) && defined(ARM32) \
  52. && (GC_GNUC_PREREQ(4, 6) || GC_CLANG_PREREQ_FULL(3, 8, 256229)))
  53. # define USE_COMPILER_TLS
  54. # elif defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) \
  55. || defined(GC_AIX_THREADS) || defined(GC_DARWIN_THREADS) \
  56. || defined(GC_FREEBSD_THREADS) || defined(GC_NETBSD_THREADS) \
  57. || defined(GC_LINUX_THREADS) || defined(GC_HAIKU_THREADS) \
  58. || defined(GC_RTEMS_PTHREADS)
  59. # define USE_PTHREAD_SPECIFIC
  60. # elif defined(GC_HPUX_THREADS)
  61. # ifdef __GNUC__
  62. # define USE_PTHREAD_SPECIFIC
  63. /* Empirically, as of gcc 3.3, USE_COMPILER_TLS doesn't work. */
  64. # else
  65. # define USE_COMPILER_TLS
  66. # endif
  67. # else
  68. # define USE_CUSTOM_SPECIFIC /* Use our own. */
  69. # endif
  70. #endif
  71. #ifndef THREAD_FREELISTS_KINDS
  72. # ifdef ENABLE_DISCLAIM
  73. # define THREAD_FREELISTS_KINDS (NORMAL+2)
  74. # else
  75. # define THREAD_FREELISTS_KINDS (NORMAL+1)
  76. # endif
  77. #endif /* !THREAD_FREELISTS_KINDS */
  78. /* One of these should be declared as the tlfs field in the */
  79. /* structure pointed to by a GC_thread. */
  80. typedef struct thread_local_freelists {
  81. void * _freelists[THREAD_FREELISTS_KINDS][TINY_FREELISTS];
  82. # define ptrfree_freelists _freelists[PTRFREE]
  83. # define normal_freelists _freelists[NORMAL]
  84. /* Note: Preserve *_freelists names for some clients. */
  85. # ifdef GC_GCJ_SUPPORT
  86. void * gcj_freelists[TINY_FREELISTS];
  87. # define ERROR_FL ((void *)(word)-1)
  88. /* Value used for gcj_freelists[-1]; allocation is */
  89. /* erroneous. */
  90. # endif
  91. /* Free lists contain either a pointer or a small count */
  92. /* reflecting the number of granules allocated at that */
  93. /* size. */
  94. /* 0 ==> thread-local allocation in use, free list */
  95. /* empty. */
  96. /* > 0, <= DIRECT_GRANULES ==> Using global allocation, */
  97. /* too few objects of this size have been */
  98. /* allocated by this thread. */
  99. /* >= HBLKSIZE => pointer to nonempty free list. */
  100. /* > DIRECT_GRANULES, < HBLKSIZE ==> transition to */
  101. /* local alloc, equivalent to 0. */
  102. # define DIRECT_GRANULES (HBLKSIZE/GRANULE_BYTES)
  103. /* Don't use local free lists for up to this much */
  104. /* allocation. */
  105. } *GC_tlfs;
  106. #if defined(USE_PTHREAD_SPECIFIC)
  107. # define GC_getspecific pthread_getspecific
  108. # define GC_setspecific pthread_setspecific
  109. # define GC_key_create pthread_key_create
  110. # define GC_remove_specific(key) pthread_setspecific(key, NULL)
  111. /* Explicitly delete the value to stop the TLS */
  112. /* destructor from being called repeatedly. */
  113. # define GC_remove_specific_after_fork(key, t) (void)0
  114. /* Should not need any action. */
  115. typedef pthread_key_t GC_key_t;
  116. #elif defined(USE_COMPILER_TLS) || defined(USE_WIN32_COMPILER_TLS)
  117. # define GC_getspecific(x) (x)
  118. # define GC_setspecific(key, v) ((key) = (v), 0)
  119. # define GC_key_create(key, d) 0
  120. # define GC_remove_specific(key) /* No need for cleanup on exit. */
  121. # define GC_remove_specific_after_fork(key, t) (void)0
  122. typedef void * GC_key_t;
  123. #elif defined(USE_WIN32_SPECIFIC)
  124. # ifndef WIN32_LEAN_AND_MEAN
  125. # define WIN32_LEAN_AND_MEAN 1
  126. # endif
  127. # define NOSERVICE
  128. EXTERN_C_END
  129. # include <windows.h>
  130. EXTERN_C_BEGIN
  131. # define GC_getspecific TlsGetValue
  132. # define GC_setspecific(key, v) !TlsSetValue(key, v)
  133. /* We assume 0 == success, msft does the opposite. */
  134. # ifndef TLS_OUT_OF_INDEXES
  135. /* this is currently missing in WinCE */
  136. # define TLS_OUT_OF_INDEXES (DWORD)0xFFFFFFFF
  137. # endif
  138. # define GC_key_create(key, d) \
  139. ((d) != 0 || (*(key) = TlsAlloc()) == TLS_OUT_OF_INDEXES ? -1 : 0)
  140. # define GC_remove_specific(key) /* No need for cleanup on exit. */
  141. /* Need TlsFree on process exit/detach? */
  142. # define GC_remove_specific_after_fork(key, t) (void)0
  143. typedef DWORD GC_key_t;
  144. #elif defined(USE_CUSTOM_SPECIFIC)
  145. EXTERN_C_END
  146. # include "private/specific.h"
  147. EXTERN_C_BEGIN
  148. #else
  149. # error implement me
  150. #endif
  151. /* Each thread structure must be initialized. */
  152. /* This call must be made from the new thread. */
  153. /* Caller holds allocation lock. */
  154. GC_INNER void GC_init_thread_local(GC_tlfs p);
  155. /* Called when a thread is unregistered, or exits. */
  156. /* We hold the allocator lock. */
  157. GC_INNER void GC_destroy_thread_local(GC_tlfs p);
  158. /* The thread support layer must arrange to mark thread-local */
  159. /* free lists explicitly, since the link field is often */
  160. /* invisible to the marker. It knows how to find all threads; */
  161. /* we take care of an individual thread freelist structure. */
  162. GC_INNER void GC_mark_thread_local_fls_for(GC_tlfs p);
  163. #ifdef GC_ASSERTIONS
  164. GC_bool GC_is_thread_tsd_valid(void *tsd);
  165. void GC_check_tls_for(GC_tlfs p);
  166. # if defined(USE_CUSTOM_SPECIFIC)
  167. void GC_check_tsd_marks(tsd *key);
  168. # endif
  169. #endif /* GC_ASSERTIONS */
  170. #ifndef GC_ATTR_TLS_FAST
  171. # define GC_ATTR_TLS_FAST /* empty */
  172. #endif
  173. extern
  174. #if defined(USE_COMPILER_TLS)
  175. __thread GC_ATTR_TLS_FAST
  176. #elif defined(USE_WIN32_COMPILER_TLS)
  177. __declspec(thread) GC_ATTR_TLS_FAST
  178. #endif
  179. GC_key_t GC_thread_key;
  180. /* This is set up by the thread_local_alloc implementation. No need */
  181. /* for cleanup on thread exit. But the thread support layer makes sure */
  182. /* that GC_thread_key is traced, if necessary. */
  183. EXTERN_C_END
  184. #endif /* THREAD_LOCAL_ALLOC */
  185. #endif /* GC_THREAD_LOCAL_ALLOC_H */