2 * Copyright (c) 2000-2005 by Hewlett-Packard Company. All rights reserved.
4 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
5 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
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.
14 /* Included indirectly from a thread-library-specific file. */
15 /* This is the interface for thread-local allocation, whose */
16 /* implementation is mostly thread-library-independent. */
17 /* Here we describe only the interface that needs to be known */
18 /* and invoked from the thread support layer; the actual */
19 /* implementation also exports GC_malloc and friends, which */
20 /* are declared in gc.h. */
22 #ifndef GC_THREAD_LOCAL_ALLOC_H
23 #define GC_THREAD_LOCAL_ALLOC_H
25 #include "private/gc_priv.h"
27 #if defined(THREAD_LOCAL_ALLOC)
29 #include "gc_inline.h"
31 # if defined(USE_HPUX_TLS)
32 # error USE_HPUX_TLS macro was replaced by USE_COMPILER_TLS
35 # if !defined(USE_PTHREAD_SPECIFIC) && !defined(USE_WIN32_SPECIFIC) && \
36 !defined(USE_WIN32_COMPILER_TLS) && !defined(USE_COMPILER_TLS) && \
37 !defined(USE_CUSTOM_SPECIFIC)
38 # if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32)
39 # if defined(__GNUC__) /* Fixed for versions past 2.95? */ \
41 # define USE_WIN32_SPECIFIC
43 # define USE_WIN32_COMPILER_TLS
45 # elif defined(LINUX) && !defined(ARM32) && \
46 (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >=3))
47 # define USE_COMPILER_TLS
48 # elif (defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) || \
49 defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS)) || \
50 defined(GC_NETBSD_THREADS)
51 # define USE_PTHREAD_SPECIFIC
52 # elif defined(GC_HPUX_THREADS)
54 # define USE_PTHREAD_SPECIFIC
55 /* Empirically, as of gcc 3.3, USE_COMPILER_TLS doesn't work. */
57 # define USE_COMPILER_TLS
60 # define USE_CUSTOM_SPECIFIC /* Use our own. */
66 /* One of these should be declared as the tlfs field in the */
67 /* structure pointed to by a GC_thread. */
68 typedef struct thread_local_freelists {
69 # ifdef THREAD_LOCAL_ALLOC
70 void * ptrfree_freelists[TINY_FREELISTS];
71 void * normal_freelists[TINY_FREELISTS];
72 # ifdef GC_GCJ_SUPPORT
73 void * gcj_freelists[TINY_FREELISTS];
74 # define ERROR_FL ((void *)(word)-1)
75 /* Value used for gcj_freelist[-1]; allocation is */
78 /* Free lists contain either a pointer or a small count */
79 /* reflecting the number of granules allocated at that */
81 /* 0 ==> thread-local allocation in use, free list */
83 /* > 0, <= DIRECT_GRANULES ==> Using global allocation, */
84 /* too few objects of this size have been */
85 /* allocated by this thread. */
86 /* >= HBLKSIZE => pointer to nonempty free list. */
87 /* > DIRECT_GRANULES, < HBLKSIZE ==> transition to */
88 /* local alloc, equivalent to 0. */
89 # define DIRECT_GRANULES (HBLKSIZE/GRANULE_BYTES)
90 /* Don't use local free lists for up to this much */
96 # if defined(USE_PTHREAD_SPECIFIC)
97 # define GC_getspecific pthread_getspecific
98 # define GC_setspecific pthread_setspecific
99 # define GC_key_create pthread_key_create
100 # define GC_remove_specific(key) /* No need for cleanup on exit. */
101 typedef pthread_key_t GC_key_t;
102 # elif defined(USE_COMPILER_TLS) || defined(USE_WIN32_COMPILER_TLS)
103 # define GC_getspecific(x) (x)
104 # define GC_setspecific(key, v) ((key) = (v), 0)
105 # define GC_key_create(key, d) 0
106 # define GC_remove_specific(key) /* No need for cleanup on exit. */
107 typedef void * GC_key_t;
108 # elif defined(USE_WIN32_SPECIFIC)
109 # include <windows.h>
110 # define GC_getspecific TlsGetValue
111 # define GC_setspecific(key, v) !TlsSetValue(key, v)
112 /* We assume 0 == success, msft does the opposite. */
113 # ifndef TLS_OUT_OF_INDEXES
114 /* this is currently missing in WinCE */
115 # define TLS_OUT_OF_INDEXES (DWORD)0xFFFFFFFF
117 # define GC_key_create(key, d) \
118 ((d) != 0 || (*(key) = TlsAlloc()) == TLS_OUT_OF_INDEXES ? -1 : 0)
119 # define GC_remove_specific(key) /* No need for cleanup on thread exit. */
120 /* Need TlsFree on process exit/detach ? */
121 typedef DWORD GC_key_t;
122 # elif defined(USE_CUSTOM_SPECIFIC)
123 # include "private/specific.h"
129 /* Each thread structure must be initialized. */
130 /* This call must be made from the new thread. */
131 /* Caller holds allocation lock. */
132 GC_INNER void GC_init_thread_local(GC_tlfs p);
134 /* Called when a thread is unregistered, or exits. */
135 /* We hold the allocator lock. */
136 GC_INNER void GC_destroy_thread_local(GC_tlfs p);
138 /* The thread support layer must arrange to mark thread-local */
139 /* free lists explicitly, since the link field is often */
140 /* invisible to the marker. It knows how to find all threads; */
141 /* we take care of an individual thread freelist structure. */
142 GC_INNER void GC_mark_thread_local_fls_for(GC_tlfs p);
145 #if defined(USE_COMPILER_TLS)
147 #elif defined(USE_WIN32_COMPILER_TLS)
150 GC_key_t GC_thread_key;
152 /* This is set up by the thread_local_alloc implementation. But the */
153 /* thread support layer calls GC_remove_specific(GC_thread_key) */
154 /* before a thread exits. */
155 /* And the thread support layer makes sure that GC_thread_key is traced,*/
158 #endif /* THREAD_LOCAL_ALLOC */
160 #endif /* GC_THREAD_LOCAL_ALLOC_H */