From 49d7fe77033f0bdabd50a2912cd58effd85452c1 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Thu, 28 Sep 2017 02:06:31 +0300 Subject: [PATCH] Support GC_init (and get_stack_base) from non-main thread on FreeBSD Issue #180 (bdwgc). Now GC_get_[main_]stack_base uses pthread_attr_get_np() and pthread_attr_getstack() to determine the stack base address. * os_dep.c [FREEBSD && !NO_PTHREAD_ATTR_GET_NP && (THREADS || USE_GET_STACKBASE_FOR_MAIN)]: Include pthread.h and pthread_np.h. * os_dep.c [FREEBSD && !NO_PTHREAD_ATTR_GET_NP && (USE_GET_STACKBASE_FOR_MAIN || THREADS && !REDIRECT_MALLOC)] (GC_get_main_stack_base): Call pthread_attr_init, pthread_attr_get_np and pthread_attr_getstack to determine the stack base address of the current thread (fall back to GC_freebsd_main_stack_base in case of failure). * os_dep.c [(GC_FREEBSD_THREADS && !NO_PTHREAD_ATTR_GET_NP] (GC_get_stack_base): Call pthread_attr_init, pthread_attr_get_np and pthread_attr_getstack to determine the stack base address of the current thread. --- os_dep.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/os_dep.c b/os_dep.c index cdd594ed..4efd6732 100644 --- a/os_dep.c +++ b/os_dep.c @@ -1182,7 +1182,11 @@ GC_INNER size_t GC_page_size = 0; && !defined(GC_OPENBSD_THREADS) \ && (!defined(GC_SOLARIS_THREADS) || defined(_STRICT_STDC)) -# if defined(LINUX) && defined(USE_GET_STACKBASE_FOR_MAIN) +# if defined(FREEBSD) && !defined(NO_PTHREAD_ATTR_GET_NP) \ + && (defined(THREADS) || defined(USE_GET_STACKBASE_FOR_MAIN)) +# include +# include /* for pthread_attr_get_np() */ +# elif defined(LINUX) && defined(USE_GET_STACKBASE_FOR_MAIN) # include # elif defined(DARWIN) && !defined(NO_PTHREAD_GET_STACKADDR_NP) /* We could use pthread_get_stackaddr_np even in case of a */ @@ -1195,14 +1199,22 @@ GC_INNER size_t GC_page_size = 0; ptr_t GC_get_main_stack_base(void) { ptr_t result; -# if defined(LINUX) && !defined(NO_PTHREAD_GETATTR_NP) \ +# if ((defined(FREEBSD) && !defined(NO_PTHREAD_ATTR_GET_NP)) \ + || (defined(LINUX) && !defined(NO_PTHREAD_GETATTR_NP))) \ && (defined(USE_GET_STACKBASE_FOR_MAIN) \ || (defined(THREADS) && !defined(REDIRECT_MALLOC))) pthread_attr_t attr; void *stackaddr; size_t size; - if (pthread_getattr_np(pthread_self(), &attr) == 0) { +# ifdef FREEBSD + if (pthread_attr_init(&attr) == 0 + && (pthread_attr_get_np(pthread_self(), &attr) == 0 + ? TRUE : (pthread_attr_destroy(&attr), FALSE))) +# else /* LINUX */ + if (pthread_getattr_np(pthread_self(), &attr) == 0) +# endif + { if (pthread_attr_getstack(&attr, &stackaddr, &size) == 0 && stackaddr != NULL) { (void)pthread_attr_destroy(&attr); @@ -1268,8 +1280,9 @@ GC_INNER size_t GC_page_size = 0; # define GET_MAIN_STACKBASE_SPECIAL #endif /* !AMIGA, !BEOS, !OPENBSD, !OS2, !Windows */ -#if (defined(GC_LINUX_THREADS) || defined(PLATFORM_ANDROID)) \ - && !defined(NO_PTHREAD_GETATTR_NP) +#if (defined(GC_FREEBSD_THREADS) && !defined(NO_PTHREAD_ATTR_GET_NP)) \ + || ((defined(GC_LINUX_THREADS) || defined(PLATFORM_ANDROID)) \ + && !defined(NO_PTHREAD_GETATTR_NP)) # include /* extern int pthread_getattr_np(pthread_t, pthread_attr_t *); */ @@ -1282,10 +1295,20 @@ GC_INNER size_t GC_page_size = 0; DCL_LOCK_STATE; # endif - if (pthread_getattr_np(pthread_self(), &attr) != 0) { +# ifdef FREEBSD + if (pthread_attr_init(&attr) != 0) + ABORT("pthread_attr_init failed"); + if (pthread_attr_get_np(pthread_self(), &attr) != 0) { + WARN("pthread_attr_get_np failed\n", 0); + (void)pthread_attr_destroy(&attr); + return GC_UNIMPLEMENTED; + } +# else /* LINUX */ + if (pthread_getattr_np(pthread_self(), &attr) != 0) { WARN("pthread_getattr_np failed\n", 0); return GC_UNIMPLEMENTED; - } + } +# endif if (pthread_attr_getstack(&attr, &(b -> mem_base), &size) != 0) { ABORT("pthread_attr_getstack failed"); } -- 2.50.1