xref: /netbsd/external/gpl3/binutils/dist/config/tls.m4 (revision 6550d01e)
1dnl Check whether the target supports TLS.
2AC_DEFUN([GCC_CHECK_TLS], [
3  GCC_ENABLE(tls, yes, [], [Use thread-local storage])
4  AC_CACHE_CHECK([whether the target supports thread-local storage],
5		 gcc_cv_have_tls, [
6    AC_RUN_IFELSE([__thread int a; int b; int main() { return a = b; }],
7      [dnl If the test case passed with dynamic linking, try again with
8       dnl static linking, but only if static linking is supported (not
9       dnl on Solaris 10).  This fails with some older Red Hat releases.
10      chktls_save_LDFLAGS="$LDFLAGS"
11      LDFLAGS="-static $LDFLAGS"
12      AC_LINK_IFELSE([int main() { return 0; }],
13	AC_RUN_IFELSE([__thread int a; int b; int main() { return a = b; }],
14		      [gcc_cv_have_tls=yes], [gcc_cv_have_tls=no],[]),
15	[gcc_cv_have_tls=yes])
16      LDFLAGS="$chktls_save_LDFLAGS"
17      if test $gcc_cv_have_tls = yes; then
18	dnl So far, the binutils and the compiler support TLS.
19	dnl Also check whether the libc supports TLS, i.e. whether a variable
20	dnl with __thread linkage has a different address in different threads.
21	dnl First, find the thread_CFLAGS necessary for linking a program that
22	dnl calls pthread_create.
23	chktls_save_CFLAGS="$CFLAGS"
24	thread_CFLAGS=failed
25	for flag in '' '-pthread' '-lpthread'; do
26	  CFLAGS="$flag $chktls_save_CFLAGS"
27	  AC_LINK_IFELSE(
28	    [AC_LANG_PROGRAM(
29	       [#include <pthread.h>
30		void *g(void *d) { return NULL; }],
31	       [pthread_t t; pthread_create(&t,NULL,g,NULL);])],
32	    [thread_CFLAGS="$flag"])
33	  if test "X$thread_CFLAGS" != Xfailed; then
34	    break
35	  fi
36	done
37	CFLAGS="$chktls_save_CFLAGS"
38	if test "X$thread_CFLAGS" != Xfailed; then
39	  CFLAGS="$thread_CFLAGS $chktls_save_CFLAGS"
40	  AC_RUN_IFELSE(
41	    [AC_LANG_PROGRAM(
42	       [#include <pthread.h>
43		__thread int a;
44		static int *a_in_other_thread;
45		static void *
46		thread_func (void *arg)
47		{
48		  a_in_other_thread = &a;
49		  return (void *)0;
50		}],
51	       [pthread_t thread;
52		void *thread_retval;
53		int *a_in_main_thread;
54		if (pthread_create (&thread, (pthread_attr_t *)0,
55				    thread_func, (void *)0))
56		  return 0;
57		a_in_main_thread = &a;
58		if (pthread_join (thread, &thread_retval))
59		  return 0;
60		return (a_in_other_thread == a_in_main_thread);])],
61	     [gcc_cv_have_tls=yes], [gcc_cv_have_tls=no], [])
62	  CFLAGS="$chktls_save_CFLAGS"
63	fi
64      fi],
65      [gcc_cv_have_tls=no],
66      [dnl This is the cross-compiling case. Assume libc supports TLS if the
67       dnl binutils and the compiler do.
68       AC_LINK_IFELSE([__thread int a; int b; int main() { return a = b; }],
69		      [gcc_cv_have_tls=yes], [gcc_cv_have_tls=no])
70      ]
71    )])
72  if test "$enable_tls $gcc_cv_have_tls" = "yes yes"; then
73    AC_DEFINE(HAVE_TLS, 1,
74	      [Define to 1 if the target supports thread-local storage.])
75  fi])
76
77dnl Check whether the target assembler supports TLS.
78AC_DEFUN([GCC_CHECK_CC_TLS], [
79  GCC_ENABLE(tls, yes, [], [Use thread-local storage])
80  AC_CACHE_CHECK([whether the target assembler supports thread-local storage],
81		 gcc_cv_have_cc_tls, [
82    AC_COMPILE_IFELSE([__thread int a; int b; int main() { return a = b; }],
83      [gcc_cv_have_cc_tls=yes], [gcc_cv_have_cc_tls=no])]
84    )])
85  if test "$enable_tls $gcc_cv_have_cc_tls" = "yes yes"; then
86    AC_DEFINE(HAVE_CC_TLS, 1,
87	      [Define to 1 if the target assembler supports thread-local storage.])
88  fi])
89