# define USE_GET_STACKBASE_FOR_MAIN
#endif
+/* Outline pthread primitives to use in GC_get_[main_]stack_base. */
+#if ((defined(FREEBSD) && defined(__GLIBC__)) /* kFreeBSD */ \
+ || defined(LINUX) || defined(PLATFORM_ANDROID)) \
+ && !defined(NO_PTHREAD_GETATTR_NP)
+# define HAVE_PTHREAD_GETATTR_NP 1
+#elif defined(FREEBSD) && !defined(__GLIBC__) \
+ && !defined(NO_PTHREAD_ATTR_GET_NP)
+# define HAVE_PTHREAD_NP_H 1 /* requires include pthread_np.h */
+# define HAVE_PTHREAD_ATTR_GET_NP 1
+#endif
+
#if defined(UNIX_LIKE) && defined(THREADS) && !defined(NO_CANCEL_SAFE) \
&& !defined(PLATFORM_ANDROID)
/* Make the code cancellation-safe. This basically means that we */
&& !defined(GC_OPENBSD_THREADS) \
&& (!defined(GC_SOLARIS_THREADS) || defined(_STRICT_STDC))
-# if defined(FREEBSD) && !defined(NO_PTHREAD_ATTR_GET_NP) \
+# if (defined(HAVE_PTHREAD_ATTR_GET_NP) || defined(HAVE_PTHREAD_GETATTR_NP)) \
&& (defined(THREADS) || defined(USE_GET_STACKBASE_FOR_MAIN))
# include <pthread.h>
-# include <pthread_np.h> /* for pthread_attr_get_np() */
-# elif defined(LINUX) && defined(USE_GET_STACKBASE_FOR_MAIN)
-# include <pthread.h>
+# ifdef HAVE_PTHREAD_NP_H
+# include <pthread_np.h> /* for pthread_attr_get_np() */
+# endif
# elif defined(DARWIN) && !defined(NO_PTHREAD_GET_STACKADDR_NP)
/* We could use pthread_get_stackaddr_np even in case of a */
/* single-threaded gclib (there is no -lpthread on Darwin). */
ptr_t GC_get_main_stack_base(void)
{
ptr_t result;
-# if ((defined(FREEBSD) && !defined(NO_PTHREAD_ATTR_GET_NP)) \
- || (defined(LINUX) && !defined(NO_PTHREAD_GETATTR_NP))) \
+# if (defined(HAVE_PTHREAD_ATTR_GET_NP) \
+ || defined(HAVE_PTHREAD_GETATTR_NP)) \
&& (defined(USE_GET_STACKBASE_FOR_MAIN) \
|| (defined(THREADS) && !defined(REDIRECT_MALLOC)))
pthread_attr_t attr;
void *stackaddr;
size_t size;
-# ifdef FREEBSD
+# ifdef HAVE_PTHREAD_ATTR_GET_NP
if (pthread_attr_init(&attr) == 0
&& (pthread_attr_get_np(pthread_self(), &attr) == 0
? TRUE : (pthread_attr_destroy(&attr), FALSE)))
-# else /* LINUX */
+# else /* HAVE_PTHREAD_GETATTR_NP */
if (pthread_getattr_np(pthread_self(), &attr) == 0)
# endif
{
# define GET_MAIN_STACKBASE_SPECIAL
#endif /* !AMIGA, !BEOS, !OPENBSD, !OS2, !Windows */
-#if (defined(GC_FREEBSD_THREADS) && !defined(NO_PTHREAD_ATTR_GET_NP)) \
- || ((defined(GC_LINUX_THREADS) || defined(PLATFORM_ANDROID)) \
- && !defined(NO_PTHREAD_GETATTR_NP))
-
+#if (defined(HAVE_PTHREAD_ATTR_GET_NP) || defined(HAVE_PTHREAD_GETATTR_NP)) \
+ && defined(THREADS) && !defined(HAVE_GET_STACK_BASE)
# include <pthread.h>
- /* extern int pthread_getattr_np(pthread_t, pthread_attr_t *); */
+# ifdef HAVE_PTHREAD_NP_H
+# include <pthread_np.h>
+# endif
GC_API int GC_CALL GC_get_stack_base(struct GC_stack_base *b)
{
DCL_LOCK_STATE;
# endif
-# ifdef FREEBSD
+# ifdef HAVE_PTHREAD_ATTR_GET_NP
if (pthread_attr_init(&attr) != 0)
ABORT("pthread_attr_init failed");
if (pthread_attr_get_np(pthread_self(), &attr) != 0) {
(void)pthread_attr_destroy(&attr);
return GC_UNIMPLEMENTED;
}
-# else /* LINUX */
+# else /* HAVE_PTHREAD_GETATTR_NP */
if (pthread_getattr_np(pthread_self(), &attr) != 0) {
WARN("pthread_getattr_np failed\n", 0);
return GC_UNIMPLEMENTED;
return GC_SUCCESS;
}
# define HAVE_GET_STACK_BASE
-#endif /* GC_LINUX_THREADS */
+#endif /* THREADS && (HAVE_PTHREAD_ATTR_GET_NP || HAVE_PTHREAD_GETATTR_NP) */
#if defined(GC_DARWIN_THREADS) && !defined(NO_PTHREAD_GET_STACKADDR_NP)
# include <pthread.h>