Import boehm-gc snapshot, taken from
[official-gcc.git] / boehm-gc / include / private / thread_local_alloc.h
blobce089edfc05eaa822ec184aec74222aad9469c64
1 /*
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 #ifdef 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
33 #endif
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(CYGWIN32) && (__GNUC__ >= 4)
40 # define USE_COMPILER_TLS
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 && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >=3))
48 # define USE_COMPILER_TLS
49 # elif defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) \
50 || defined(GC_AIX_THREADS) || defined(GC_DARWIN_THREADS) \
51 || defined(GC_FREEBSD_THREADS) || defined(GC_NETBSD_THREADS) \
52 || defined(GC_RTEMS_PTHREADS)
53 # define USE_PTHREAD_SPECIFIC
54 # elif defined(GC_HPUX_THREADS)
55 # ifdef __GNUC__
56 # define USE_PTHREAD_SPECIFIC
57 /* Empirically, as of gcc 3.3, USE_COMPILER_TLS doesn't work. */
58 # else
59 # define USE_COMPILER_TLS
60 # endif
61 # else
62 # define USE_CUSTOM_SPECIFIC /* Use our own. */
63 # endif
64 #endif
66 #include <stdlib.h>
68 /* One of these should be declared as the tlfs field in the */
69 /* structure pointed to by a GC_thread. */
70 typedef struct thread_local_freelists {
71 void * ptrfree_freelists[TINY_FREELISTS];
72 void * normal_freelists[TINY_FREELISTS];
73 # ifdef GC_GCJ_SUPPORT
74 void * gcj_freelists[TINY_FREELISTS];
75 # define ERROR_FL ((void *)(word)-1)
76 /* Value used for gcj_freelist[-1]; allocation is */
77 /* erroneous. */
78 # endif
79 # ifdef ENABLE_DISCLAIM
80 void * finalized_freelists[TINY_FREELISTS];
81 # endif
82 /* Free lists contain either a pointer or a small count */
83 /* reflecting the number of granules allocated at that */
84 /* size. */
85 /* 0 ==> thread-local allocation in use, free list */
86 /* empty. */
87 /* > 0, <= DIRECT_GRANULES ==> Using global allocation, */
88 /* too few objects of this size have been */
89 /* allocated by this thread. */
90 /* >= HBLKSIZE => pointer to nonempty free list. */
91 /* > DIRECT_GRANULES, < HBLKSIZE ==> transition to */
92 /* local alloc, equivalent to 0. */
93 # define DIRECT_GRANULES (HBLKSIZE/GRANULE_BYTES)
94 /* Don't use local free lists for up to this much */
95 /* allocation. */
96 } *GC_tlfs;
98 #if defined(USE_PTHREAD_SPECIFIC)
99 # define GC_getspecific pthread_getspecific
100 # define GC_setspecific pthread_setspecific
101 # define GC_key_create pthread_key_create
102 # define GC_remove_specific(key) /* No need for cleanup on exit. */
103 typedef pthread_key_t GC_key_t;
104 #elif defined(USE_COMPILER_TLS) || defined(USE_WIN32_COMPILER_TLS)
105 # define GC_getspecific(x) (x)
106 # define GC_setspecific(key, v) ((key) = (v), 0)
107 # define GC_key_create(key, d) 0
108 # define GC_remove_specific(key) /* No need for cleanup on exit. */
109 typedef void * GC_key_t;
110 #elif defined(USE_WIN32_SPECIFIC)
111 # ifndef WIN32_LEAN_AND_MEAN
112 # define WIN32_LEAN_AND_MEAN 1
113 # endif
114 # define NOSERVICE
115 # include <windows.h>
116 # define GC_getspecific TlsGetValue
117 # define GC_setspecific(key, v) !TlsSetValue(key, v)
118 /* We assume 0 == success, msft does the opposite. */
119 # ifndef TLS_OUT_OF_INDEXES
120 /* this is currently missing in WinCE */
121 # define TLS_OUT_OF_INDEXES (DWORD)0xFFFFFFFF
122 # endif
123 # define GC_key_create(key, d) \
124 ((d) != 0 || (*(key) = TlsAlloc()) == TLS_OUT_OF_INDEXES ? -1 : 0)
125 # define GC_remove_specific(key) /* No need for cleanup on exit. */
126 /* Need TlsFree on process exit/detach? */
127 typedef DWORD GC_key_t;
128 #elif defined(USE_CUSTOM_SPECIFIC)
129 # include "private/specific.h"
130 #else
131 # error implement me
132 #endif
134 /* Each thread structure must be initialized. */
135 /* This call must be made from the new thread. */
136 /* Caller holds allocation lock. */
137 GC_INNER void GC_init_thread_local(GC_tlfs p);
139 /* Called when a thread is unregistered, or exits. */
140 /* We hold the allocator lock. */
141 GC_INNER void GC_destroy_thread_local(GC_tlfs p);
143 /* The thread support layer must arrange to mark thread-local */
144 /* free lists explicitly, since the link field is often */
145 /* invisible to the marker. It knows how to find all threads; */
146 /* we take care of an individual thread freelist structure. */
147 GC_INNER void GC_mark_thread_local_fls_for(GC_tlfs p);
149 #ifdef ENABLE_DISCLAIM
150 GC_EXTERN ptr_t * GC_finalized_objfreelist;
151 #endif
153 extern
154 #if defined(USE_COMPILER_TLS)
155 __thread
156 #elif defined(USE_WIN32_COMPILER_TLS)
157 __declspec(thread)
158 #endif
159 GC_key_t GC_thread_key;
160 /* This is set up by the thread_local_alloc implementation. No need */
161 /* for cleanup on thread exit. But the thread support layer makes sure */
162 /* that GC_thread_key is traced, if necessary. */
164 #endif /* THREAD_LOCAL_ALLOC */
166 #endif /* GC_THREAD_LOCAL_ALLOC_H */