2 * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
3 * Copyright (c) 1996 by Silicon Graphics. All rights reserved.
4 * Copyright (c) 1998 by Fergus Henderson. All rights reserved.
5 * Copyright (c) 2000-2009 by Hewlett-Packard Development Company.
8 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
9 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
11 * Permission is hereby granted to use or copy this program
12 * for any purpose, provided the above notices are retained on all copies.
13 * Permission to modify the code and to distribute modified code is granted,
14 * provided the above notices are retained, and a notice that the code was
15 * modified is included with the above copyright notice.
18 /* This should never be included directly; it is included only from gc.h. */
19 /* We separate it only to make gc.h more suitable as documentation. */
22 /* Some tests for old macros. These violate our namespace rules and */
23 /* will disappear shortly. Use the GC_ names. */
24 #if defined(SOLARIS_THREADS) || defined(_SOLARIS_THREADS) \
25 || defined(_SOLARIS_PTHREADS) || defined(GC_SOLARIS_PTHREADS)
26 /* We no longer support old style Solaris threads. */
27 /* GC_SOLARIS_THREADS now means pthreads. */
28 # ifndef GC_SOLARIS_THREADS
29 # define GC_SOLARIS_THREADS
32 #if defined(IRIX_THREADS)
33 # define GC_IRIX_THREADS
35 #if defined(DGUX_THREADS) && !defined(GC_DGUX386_THREADS)
36 # define GC_DGUX386_THREADS
38 #if defined(AIX_THREADS)
39 # define GC_AIX_THREADS
41 #if defined(HPUX_THREADS)
42 # define GC_HPUX_THREADS
44 #if defined(OSF1_THREADS)
45 # define GC_OSF1_THREADS
47 #if defined(LINUX_THREADS)
48 # define GC_LINUX_THREADS
50 #if defined(WIN32_THREADS)
51 # define GC_WIN32_THREADS
53 #if defined(RTEMS_THREADS)
54 # define GC_RTEMS_PTHREADS
56 #if defined(USE_LD_WRAP)
57 # define GC_USE_LD_WRAP
60 #if defined(GC_WIN32_PTHREADS) && !defined(GC_WIN32_THREADS)
61 /* Using pthreads-w32 library. */
62 # define GC_WIN32_THREADS
65 #if defined(GC_AIX_THREADS) || defined(GC_DARWIN_THREADS) \
66 || defined(GC_DGUX386_THREADS) || defined(GC_FREEBSD_THREADS) \
67 || defined(GC_GNU_THREADS) || defined(GC_HPUX_THREADS) \
68 || defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) \
69 || defined(GC_NETBSD_THREADS) || defined(GC_OPENBSD_THREADS) \
70 || defined(GC_OSF1_THREADS) || defined(GC_SOLARIS_THREADS) \
71 || defined(GC_WIN32_THREADS) || defined(GC_RTEMS_PTHREADS)
75 #elif defined(GC_THREADS)
76 # if defined(__linux__)
77 # define GC_LINUX_THREADS
79 # if !defined(__linux__) && (defined(_PA_RISC1_1) || defined(_PA_RISC2_0) \
80 || defined(hppa) || defined(__HPPA)) \
81 || (defined(__ia64) && defined(_HPUX_SOURCE))
82 # define GC_HPUX_THREADS
84 # if !defined(__linux__) && (defined(__alpha) || defined(__alpha__))
85 # define GC_OSF1_THREADS
87 # if defined(__mips) && !defined(__linux__)
88 # define GC_IRIX_THREADS
90 # if defined(__sparc) && !defined(__linux__) \
91 || defined(sun) && (defined(i386) || defined(__i386__) \
92 || defined(__amd64__))
93 # define GC_SOLARIS_THREADS
94 # elif defined(__APPLE__) && defined(__MACH__)
95 # define GC_DARWIN_THREADS
96 # elif defined(__OpenBSD__)
97 # define GC_OPENBSD_THREADS
98 # elif !defined(GC_LINUX_THREADS) && !defined(GC_HPUX_THREADS) \
99 && !defined(GC_OSF1_THREADS) && !defined(GC_IRIX_THREADS)
100 /* FIXME: Should we really need for FreeBSD and NetBSD to check */
101 /* that no other GC_xxx_THREADS macro is set? */
102 # if defined(__FreeBSD__) || defined(__DragonFly__)
103 # define GC_FREEBSD_THREADS
104 # elif defined(__NetBSD__)
105 # define GC_NETBSD_THREADS
108 # if defined(DGUX) && (defined(i386) || defined(__i386__))
109 # define GC_DGUX386_THREADS
112 # define GC_AIX_THREADS
114 # if (defined(_WIN32) || defined(_MSC_VER) || defined(__BORLANDC__) \
115 || defined(__CYGWIN32__) || defined(__CYGWIN__) || defined(__CEGCC__) \
116 || defined(_WIN32_WCE) || defined(__MINGW32__)) \
117 && !defined(GC_WIN32_THREADS)
118 /* Either posix or native Win32 threads. */
119 # define GC_WIN32_THREADS
121 # if defined(__rtems__) && (defined(i386) || defined(__i386__))
122 # define GC_RTEMS_PTHREADS
124 #endif /* GC_THREADS */
127 #if (!defined(GC_WIN32_THREADS) || defined(GC_WIN32_PTHREADS) \
128 || defined(GC_RTEMS_PTHREADS) || defined(__CYGWIN32__) \
129 || defined(__CYGWIN__)) && defined(GC_THREADS)
134 #if !defined(_PTHREADS) && defined(GC_NETBSD_THREADS)
138 #if defined(GC_DGUX386_THREADS) && !defined(_POSIX4A_DRAFT10_SOURCE)
139 # define _POSIX4A_DRAFT10_SOURCE 1
142 #if !defined(_REENTRANT) && defined(GC_PTHREADS) && !defined(GC_WIN32_THREADS)
143 /* Better late than never. This fails if system headers that depend */
144 /* on this were previously included. */
149 #if !defined(_WIN32_WCE) || defined(__GNUC__)
151 # if defined(__MINGW32__) && !defined(_WIN32_WCE)
153 /* We mention uintptr_t. */
154 /* Perhaps this should be included in pure msft environments */
157 #else /* _WIN32_WCE */
158 /* Yet more kludges for WinCE. */
159 # include <stdlib.h> /* size_t is defined here */
160 # ifndef _PTRDIFF_T_DEFINED
161 /* ptrdiff_t is not defined */
162 # define _PTRDIFF_T_DEFINED
163 typedef long ptrdiff_t;
165 #endif /* _WIN32_WCE */
167 #if defined(_DLL) && !defined(GC_NOT_DLL) && !defined(GC_DLL) \
168 && !defined(__GNUC__)
172 #if defined(GC_DLL) && !defined(GC_API)
174 # if defined(__MINGW32__) || defined(__CEGCC__)
176 # define GC_API __declspec(dllexport)
178 # define GC_API __declspec(dllimport)
181 # elif defined(_MSC_VER) || defined(__DMC__) || defined(__BORLANDC__) \
182 || defined(__CYGWIN__)
184 # define GC_API extern __declspec(dllexport)
186 # define GC_API __declspec(dllimport)
189 # elif defined(__WATCOMC__)
191 # define GC_API extern __declspec(dllexport)
193 # define GC_API extern __declspec(dllimport)
196 # elif defined(__GNUC__)
197 /* Only matters if used in conjunction with -fvisibility=hidden option. */
198 # if __GNUC__ >= 4 && defined(GC_BUILD)
199 # define GC_API extern __attribute__((__visibility__("default")))
205 # define GC_API extern
213 # define GC_CALLBACK GC_CALL
216 #ifndef GC_ATTR_MALLOC
217 /* 'malloc' attribute should be used for all malloc-like functions */
218 /* (to tell the compiler that a function may be treated as if any */
219 /* non-NULL pointer it returns cannot alias any other pointer valid */
220 /* when the function returns). If the client code violates this rule */
221 /* by using custom GC_oom_func then define GC_OOM_FUNC_RETURNS_ALIAS. */
222 # if !defined(GC_OOM_FUNC_RETURNS_ALIAS) && defined(__GNUC__) \
223 && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
224 # define GC_ATTR_MALLOC __attribute__((__malloc__))
226 # define GC_ATTR_MALLOC
230 #ifndef GC_ATTR_ALLOC_SIZE
231 /* 'alloc_size' attribute improves __builtin_object_size correctness. */
232 /* Only single-argument form of 'alloc_size' attribute is used. */
233 # if defined(__GNUC__) && (__GNUC__ > 4 \
234 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 && !defined(__ICC)))
235 # define GC_ATTR_ALLOC_SIZE(argnum) __attribute__((__alloc_size__(argnum)))
237 # define GC_ATTR_ALLOC_SIZE(argnum)
241 #if defined(__sgi) && !defined(__GNUC__) && _COMPILER_VERSION >= 720
242 # define GC_ADD_CALLER
243 # define GC_RETURN_ADDR (GC_word)__return_address
246 #if defined(__linux__) || defined(__GLIBC__)
247 # if !defined(__native_client__)
248 # include <features.h>
250 # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
251 && !defined(__ia64__) && !defined(__UCLIBC__) \
252 && !defined(GC_HAVE_BUILTIN_BACKTRACE)
253 # define GC_HAVE_BUILTIN_BACKTRACE
255 # if defined(__i386__) || defined(__x86_64__)
256 # define GC_CAN_SAVE_CALL_STACKS
260 #if defined(_MSC_VER) && _MSC_VER >= 1200 /* version 12.0+ (MSVC 6.0+) */ \
261 && !defined(_AMD64_) && !defined(_M_X64) && !defined(_WIN32_WCE) \
262 && !defined(GC_HAVE_NO_BUILTIN_BACKTRACE) \
263 && !defined(GC_HAVE_BUILTIN_BACKTRACE)
264 # define GC_HAVE_BUILTIN_BACKTRACE
267 #if defined(GC_HAVE_BUILTIN_BACKTRACE) && !defined(GC_CAN_SAVE_CALL_STACKS)
268 # define GC_CAN_SAVE_CALL_STACKS
271 #if defined(__sparc__)
272 # define GC_CAN_SAVE_CALL_STACKS
275 /* If we're on an a platform on which we can't save call stacks, but */
276 /* gcc is normally used, we go ahead and define GC_ADD_CALLER. */
277 /* We make this decision independent of whether gcc is actually being */
278 /* used, in order to keep the interface consistent, and allow mixing */
280 /* This may also be desirable if it is possible but expensive to */
281 /* retrieve the call chain. */
282 #if (defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) \
283 || defined(__FreeBSD__) || defined(__DragonFly__) \
284 || defined(PLATFORM_ANDROID)) && !defined(GC_CAN_SAVE_CALL_STACKS)
285 # define GC_ADD_CALLER
286 # if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
287 /* gcc knows how to retrieve return address, but we don't know */
288 /* how to generate call stacks. */
289 # define GC_RETURN_ADDR (GC_word)__builtin_return_address(0)
291 /* Just pass 0 for gcc compatibility. */
292 # define GC_RETURN_ADDR 0
294 #endif /* !GC_CAN_SAVE_CALL_STACKS */
298 # if (defined(GC_DARWIN_THREADS) || defined(GC_WIN32_PTHREADS) \
299 || defined(__native_client__) || defined(GC_RTEMS_PTHREADS)) \
300 && !defined(GC_NO_DLOPEN)
301 /* Either there is no dlopen() or we do not need to intercept it. */
302 # define GC_NO_DLOPEN
305 # if (defined(GC_DARWIN_THREADS) || defined(GC_WIN32_PTHREADS) \
306 || defined(GC_OPENBSD_THREADS) || defined(__native_client__)) \
307 && !defined(GC_NO_PTHREAD_SIGMASK)
308 /* Either there is no pthread_sigmask() or no need to intercept it. */
309 # define GC_NO_PTHREAD_SIGMASK
312 # if defined(__native_client__)
313 /* At present, NaCl pthread_create() prototype does not have */
314 /* "const" for its "attr" argument; also, NaCl pthread_exit() one */
315 /* does not have "noreturn" attribute. */
316 # ifndef GC_PTHREAD_CREATE_CONST
317 # define GC_PTHREAD_CREATE_CONST /* empty */
319 # ifndef GC_PTHREAD_EXIT_ATTRIBUTE
320 # define GC_PTHREAD_EXIT_ATTRIBUTE /* empty */
324 # if !defined(GC_PTHREAD_EXIT_ATTRIBUTE) && !defined(PLATFORM_ANDROID) \
325 && (defined(GC_LINUX_THREADS) || defined(GC_SOLARIS_THREADS))
326 /* Intercept pthread_exit on Linux and Solaris. */
327 # if defined(__GNUC__) /* since GCC v2.7 */
328 # define GC_PTHREAD_EXIT_ATTRIBUTE __attribute__((__noreturn__))
329 # elif defined(__NORETURN) /* used in Solaris */
330 # define GC_PTHREAD_EXIT_ATTRIBUTE __NORETURN
332 # define GC_PTHREAD_EXIT_ATTRIBUTE /* empty */
336 # if (!defined(GC_PTHREAD_EXIT_ATTRIBUTE) || defined(__native_client__)) \
337 && !defined(GC_NO_PTHREAD_CANCEL)
338 /* Either there is no pthread_cancel() or no need to intercept it. */
339 # define GC_NO_PTHREAD_CANCEL
342 #endif /* GC_PTHREADS */