Home | History | Annotate | Download | only in config
      1 dnl Check whether the target supports TLS.
      2 AC_DEFUN([GCC_CHECK_TLS], [
      3   AC_REQUIRE([AC_CANONICAL_HOST])
      4   GCC_ENABLE(tls, yes, [], [Use thread-local storage])
      5   AC_CACHE_CHECK([whether the target supports thread-local storage],
      6 		 gcc_cv_have_tls, [
      7     AC_RUN_IFELSE([__thread int a; int b; int main() { return a = b; }],
      8       [dnl If the test case passed with dynamic linking, try again with
      9        dnl static linking, but only if static linking is supported (not
     10        dnl on Solaris 10).  This fails with some older Red Hat releases.
     11       chktls_save_LDFLAGS="$LDFLAGS"
     12       LDFLAGS="-static $LDFLAGS"
     13       AC_LINK_IFELSE([int main() { return 0; }],
     14 	[AC_RUN_IFELSE([__thread int a; int b; int main() { return a = b; }],
     15 		       [gcc_cv_have_tls=yes], [gcc_cv_have_tls=no],[])],
     16 	[gcc_cv_have_tls=yes])
     17       LDFLAGS="$chktls_save_LDFLAGS"
     18       if test $gcc_cv_have_tls = yes; then
     19 	dnl So far, the binutils and the compiler support TLS.
     20 	dnl Also check whether the libc supports TLS, i.e. whether a variable
     21 	dnl with __thread linkage has a different address in different threads.
     22 	dnl First, find the thread_CFLAGS necessary for linking a program that
     23 	dnl calls pthread_create.
     24 	chktls_save_CFLAGS="$CFLAGS"
     25 	thread_CFLAGS=failed
     26 	for flag in '' '-pthread' '-lpthread'; do
     27 	  CFLAGS="$flag $chktls_save_CFLAGS"
     28 	  AC_LINK_IFELSE(
     29 	    [AC_LANG_PROGRAM(
     30 	       [#include <pthread.h>
     31 		void *g(void *d) { return NULL; }],
     32 	       [pthread_t t; pthread_create(&t,NULL,g,NULL);])],
     33 	    [thread_CFLAGS="$flag"])
     34 	  if test "X$thread_CFLAGS" != Xfailed; then
     35 	    break
     36 	  fi
     37 	done
     38 	CFLAGS="$chktls_save_CFLAGS"
     39 	if test "X$thread_CFLAGS" != Xfailed; then
     40 	  CFLAGS="$thread_CFLAGS $chktls_save_CFLAGS"
     41  	  dnl Test for an old glibc bug that violated the __thread property.
     42 	  dnl Use volatile to ensure the compiler won't optimize away pointer
     43 	  dnl accesses it might otherwise assume to be redundant, or reorder 
     44 	  dnl them and reuse storage, which might lead to them pointing to
     45 	  dnl the same location.
     46 	  AC_RUN_IFELSE(
     47 	    [AC_LANG_PROGRAM(
     48 	       [#include <pthread.h>
     49 		__thread int a;
     50 		static int *volatile a_in_other_thread;
     51 		static void *
     52 		thread_func (void *arg)
     53 		{
     54 		  a_in_other_thread = &a;
     55 		  return (void *)0;
     56 		}],
     57 	       [pthread_t thread;
     58 		void *thread_retval;
     59 		int *volatile a_in_main_thread;
     60 		a_in_main_thread = &a;
     61 		if (pthread_create (&thread, (pthread_attr_t *)0,
     62 				    thread_func, (void *)0))
     63 		  return 0;
     64 		if (pthread_join (thread, &thread_retval))
     65 		  return 0;
     66 		return (a_in_other_thread == a_in_main_thread);])],
     67 	     [gcc_cv_have_tls=yes], [gcc_cv_have_tls=no], [])
     68 	  CFLAGS="$chktls_save_CFLAGS"
     69 	fi
     70       fi],
     71       [gcc_cv_have_tls=no],
     72       [dnl This is the cross-compiling case. Assume libc supports TLS if the
     73        dnl binutils and the compiler do.
     74        AC_LINK_IFELSE([__thread int a; int b; int main() { return a = b; }],
     75 	 [chktls_save_LDFLAGS="$LDFLAGS"
     76 	  dnl Shared library options may depend on the host; this check
     77 	  dnl is only known to be needed for GNU/Linux.
     78 	  case $host in
     79 	    *-*-linux*)
     80 	      LDFLAGS="-shared -Wl,--no-undefined $LDFLAGS"
     81 	      ;;
     82 	  esac
     83 	  chktls_save_CFLAGS="$CFLAGS"
     84 	  CFLAGS="-fPIC $CFLAGS"
     85 	  dnl If -shared works, test if TLS works in a shared library.
     86 	  AC_LINK_IFELSE([int f() { return 0; }],
     87 	    [AC_LINK_IFELSE([__thread int a; int b; int f() { return a = b; }],
     88 	      [gcc_cv_have_tls=yes],
     89 	      [gcc_cv_have_tls=no])],
     90 	    [gcc_cv_have_tls=yes])
     91 	  CFLAGS="$chktls_save_CFLAGS"
     92 	  LDFLAGS="$chktls_save_LDFLAGS"], [gcc_cv_have_tls=no])
     93       ]
     94     )])
     95   if test "$enable_tls $gcc_cv_have_tls" = "yes yes"; then
     96     AC_DEFINE(HAVE_TLS, 1,
     97 	      [Define to 1 if the target supports thread-local storage.])
     98   fi])
     99 
    100 dnl Check whether the target assembler supports TLS.
    101 AC_DEFUN([GCC_CHECK_CC_TLS], [
    102   GCC_ENABLE(tls, yes, [], [Use thread-local storage])
    103   AC_CACHE_CHECK([whether the target assembler supports thread-local storage],
    104 		 gcc_cv_have_cc_tls, [
    105     AC_COMPILE_IFELSE([__thread int a; int b; int main() { return a = b; }],
    106       [gcc_cv_have_cc_tls=yes], [gcc_cv_have_cc_tls=no])]
    107     )])
    108   if test "$enable_tls $gcc_cv_have_cc_tls" = "yes yes"; then
    109     AC_DEFINE(HAVE_CC_TLS, 1,
    110 	      [Define to 1 if the target assembler supports thread-local storage.])
    111   fi])
    112 
    113 dnl Check whether TLS is emulated.
    114 AC_DEFUN([GCC_CHECK_EMUTLS], [
    115   AC_CACHE_CHECK([whether the thread-local storage support is from emutls],
    116   		 gcc_cv_use_emutls, [
    117     gcc_cv_use_emutls=no
    118     echo '__thread int a; int b; int main() { return a = b; }' > conftest.c
    119     if AC_TRY_COMMAND(${CC-cc} -Werror -S -o conftest.s conftest.c 1>&AS_MESSAGE_LOG_FD); then
    120       if grep __emutls_get_address conftest.s > /dev/null; then
    121 	gcc_cv_use_emutls=yes
    122       fi
    123     fi
    124     rm -f conftest.*
    125     ])
    126   if test "$gcc_cv_use_emutls" = "yes" ; then
    127     AC_DEFINE(USE_EMUTLS, 1,
    128       	      [Define to 1 if the target use emutls for thread-local storage.])
    129   fi])
    130