/libs/headers/gc/private/thread_local_alloc.h

http://github.com/nddrylliog/ooc · C++ Header · 154 lines · 83 code · 18 blank · 53 comment · 23 complexity · 02ae226f74c0a93e8dee57c512a65547 MD5 · raw file

  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. #include "private/gc_priv.h"
  21. #if defined(THREAD_LOCAL_ALLOC)
  22. #include "gc_inline.h"
  23. # if defined USE_HPUX_TLS
  24. # error USE_HPUX_TLS macro was replaced by USE_COMPILER_TLS
  25. # endif
  26. # if !defined(USE_PTHREAD_SPECIFIC) && !defined(USE_WIN32_SPECIFIC) && \
  27. !defined(USE_WIN32_COMPILER_TLS) && !defined(USE_COMPILER_TLS) && \
  28. !defined(USE_CUSTOM_SPECIFIC)
  29. # if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32)
  30. # if defined(__GNUC__) /* Fixed for versions past 2.95? */
  31. # define USE_WIN32_SPECIFIC
  32. # else
  33. # define USE_WIN32_COMPILER_TLS
  34. # endif /* !GNU */
  35. # elif defined(LINUX) && !defined(ARM32) && \
  36. (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >=3))
  37. # define USE_COMPILER_TLS
  38. # elif (defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) || \
  39. defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS)) || \
  40. defined(GC_NETBSD_THREADS)
  41. # define USE_PTHREAD_SPECIFIC
  42. # elif defined(GC_HPUX_THREADS)
  43. # ifdef __GNUC__
  44. # define USE_PTHREAD_SPECIFIC
  45. /* Empirically, as of gcc 3.3, USE_COMPILER_TLS doesn't work. */
  46. # else
  47. # define USE_COMPILER_TLS
  48. # endif
  49. # else
  50. # define USE_CUSTOM_SPECIFIC /* Use our own. */
  51. # endif
  52. # endif
  53. # include <stdlib.h>
  54. /* One of these should be declared as the tlfs field in the */
  55. /* structure pointed to by a GC_thread. */
  56. typedef struct thread_local_freelists {
  57. # ifdef THREAD_LOCAL_ALLOC
  58. void * ptrfree_freelists[TINY_FREELISTS];
  59. void * normal_freelists[TINY_FREELISTS];
  60. # ifdef GC_GCJ_SUPPORT
  61. void * gcj_freelists[TINY_FREELISTS];
  62. # define ERROR_FL (void *)(-1)
  63. /* Value used for gcj_freelist[-1]; allocation is */
  64. /* erroneous. */
  65. # endif
  66. /* Free lists contain either a pointer or a small count */
  67. /* reflecting the number of granules allocated at that */
  68. /* size. */
  69. /* 0 ==> thread-local allocation in use, free list */
  70. /* empty. */
  71. /* > 0, <= DIRECT_GRANULES ==> Using global allocation, */
  72. /* too few objects of this size have been */
  73. /* allocated by this thread. */
  74. /* >= HBLKSIZE => pointer to nonempty free list. */
  75. /* > DIRECT_GRANULES, < HBLKSIZE ==> transition to */
  76. /* local alloc, equivalent to 0. */
  77. # define DIRECT_GRANULES (HBLKSIZE/GRANULE_BYTES)
  78. /* Don't use local free lists for up to this much */
  79. /* allocation. */
  80. # endif
  81. } *GC_tlfs;
  82. # if defined(USE_PTHREAD_SPECIFIC)
  83. # define GC_getspecific pthread_getspecific
  84. # define GC_setspecific pthread_setspecific
  85. # define GC_key_create pthread_key_create
  86. # define GC_remove_specific(key) /* No need for cleanup on exit. */
  87. typedef pthread_key_t GC_key_t;
  88. # elif defined(USE_COMPILER_TLS) || defined(USE_WIN32_COMPILER_TLS)
  89. # define GC_getspecific(x) (x)
  90. # define GC_setspecific(key, v) ((key) = (v), 0)
  91. # define GC_key_create(key, d) 0
  92. # define GC_remove_specific(key) /* No need for cleanup on exit. */
  93. typedef void * GC_key_t;
  94. # elif defined(USE_WIN32_SPECIFIC)
  95. # include <windows.h>
  96. # define GC_getspecific TlsGetValue
  97. # define GC_setspecific(key, v) !TlsSetValue(key, v)
  98. /* We assume 0 == success, msft does the opposite. */
  99. # define GC_key_create(key, d) \
  100. ((d) != 0? (ABORT("Destructor unsupported by TlsAlloc"),0) \
  101. : ((*(key) = TlsAlloc()) == TLS_OUT_OF_INDEXES? \
  102. (ABORT("Out of tls"), 0): \
  103. 0))
  104. # define GC_remove_specific(key) /* No need for cleanup on thread exit. */
  105. /* Need TlsFree on process exit/detach ? */
  106. typedef DWORD GC_key_t;
  107. # elif defined(USE_CUSTOM_SPECIFIC)
  108. # include "private/specific.h"
  109. # else
  110. # error implement me
  111. # endif
  112. /* Each thread structure must be initialized. */
  113. /* This call must be made from the new thread. */
  114. /* Caller holds allocation lock. */
  115. void GC_init_thread_local(GC_tlfs p);
  116. /* Called when a thread is unregistered, or exits. */
  117. /* We hold the allocator lock. */
  118. void GC_destroy_thread_local(GC_tlfs p);
  119. /* The thread support layer must arrange to mark thread-local */
  120. /* free lists explicitly, since the link field is often */
  121. /* invisible to the marker. It knows hoe to find all threads; */
  122. /* we take care of an individual thread freelist structure. */
  123. void GC_mark_thread_local_fls_for(GC_tlfs p);
  124. extern
  125. #if defined(USE_COMPILER_TLS)
  126. __thread
  127. #elif defined(USE_WIN32_COMPILER_TLS)
  128. __declspec(thread)
  129. #endif
  130. GC_key_t GC_thread_key;
  131. /* This is set up by the thread_local_alloc implementation. But the */
  132. /* thread support layer calls GC_remove_specific(GC_thread_key) */
  133. /* before a thread exits. */
  134. /* And the thread support layer makes sure that GC_thread_key is traced,*/
  135. /* if necessary. */
  136. #endif /* THREAD_LOCAL_ALLOC */