+dnl Work out the size of the epoll_events struct on GNU/Linux.
+AC_CACHE_CHECK([epoll_event size],
+[libgo_cv_c_epoll_event_size],
+[AC_COMPUTE_INT(libgo_cv_c_epoll_event_size,
+[sizeof (struct epoll_event)],
+[#include <sys/epoll.h>],
+[libgo_cv_c_epoll_event_size=0])])
+SIZEOF_STRUCT_EPOLL_EVENT=${libgo_cv_c_epoll_event_size}
+AC_SUBST(SIZEOF_STRUCT_EPOLL_EVENT)
+
+dnl Work out the offset of the fd field in the epoll_events struct on
+dnl GNU/Linux.
+AC_CACHE_CHECK([epoll_event data.fd offset],
+[libgo_cv_c_epoll_event_fd_offset],
+[AC_COMPUTE_INT(libgo_cv_c_epoll_event_fd_offset,
+[offsetof (struct epoll_event, data.fd)],
+[#include <stddef.h>
+#include <sys/epoll.h>],
+[libgo_cv_c_epoll_event_fd_offset=0])])
+STRUCT_EPOLL_EVENT_FD_OFFSET=${libgo_cv_c_epoll_event_fd_offset}
+AC_SUBST(STRUCT_EPOLL_EVENT_FD_OFFSET)
+
+dnl See if struct exception is defined in <math.h>.
+AC_CHECK_TYPE([struct exception],
+[libgo_has_struct_exception=yes],
+[libgo_has_struct_exception=no],
+[#include <math.h>])
+if test "$libgo_has_struct_exception" = "yes"; then
+ AC_DEFINE(HAVE_STRUCT_EXCEPTION, 1,
+ [Define to 1 if <math.h> defines struct exception])
+fi
+
+dnl Check if makecontext expects the uc_stack member of ucontext to point
+dnl to the top of the stack.
+case "$target" in
+ sparc*-*-solaris2.[[89]]*)
+ libgo_cv_lib_makecontext_stack_top=yes
+ ;;
+ *)
+ libgo_cv_lib_makecontext_stack_top=no
+ ;;
+esac
+if test "$libgo_cv_lib_makecontext_stack_top" = "yes"; then
+ AC_DEFINE(MAKECONTEXT_STACK_TOP, 1,
+ [Define if makecontext expects top of stack in uc_stack.])
+fi
+
+dnl See whether setcontext changes the value of TLS variables.
+AC_CACHE_CHECK([whether setcontext clobbers TLS variables],
+[libgo_cv_lib_setcontext_clobbers_tls],
+[CFLAGS_hold="$CFLAGS"
+CFLAGS="$PTHREAD_CFLAGS"
+LIBS_hold="$LIBS"
+LIBS="$LIBS $PTHREAD_LIBS"
+AC_CHECK_SIZEOF([void *])
+AS_VAR_ARITH([ptr_type_size], [$ac_cv_sizeof_void_p \* 8])
+AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([
+#include <pthread.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+__thread int tls;
+
+static char stack[[10 * 1024 * 1024]];
+static ucontext_t c;
+
+/* Called via makecontext/setcontext. */
+
+static void
+cfn (void)
+{
+ exit (tls);
+}
+
+/* Called via pthread_create. */
+
+static void *
+tfn (void *dummy)
+{
+ /* The thread should still see this value after calling
+ setcontext. */
+ tls = 0;
+
+ setcontext (&c);
+
+ /* The call to setcontext should not return. */
+ abort ();
+}
+
+int
+main ()
+{
+ pthread_t tid;
+
+ /* The thread should not see this value. */
+ tls = 1;
+
+ if (getcontext (&c) < 0)
+ abort ();
+
+ c.uc_stack.ss_sp = stack;
+#ifdef MAKECONTEXT_STACK_TOP
+ c.uc_stack.ss_sp += sizeof stack;
+#endif
+ c.uc_stack.ss_flags = 0;
+ c.uc_stack.ss_size = sizeof stack;
+ c.uc_link = NULL;
+ makecontext (&c, cfn, 0);
+
+ if (pthread_create (&tid, NULL, tfn, NULL) != 0)
+ abort ();
+
+ if (pthread_join (tid, NULL) != 0)
+ abort ();
+
+ /* The thread should have called exit. */
+ abort ();
+}
+])],
+[libgo_cv_lib_setcontext_clobbers_tls=no],
+[libgo_cv_lib_setcontext_clobbers_tls=yes],
+[case "$target:$ptr_type_size" in
+ i?86-*-solaris2.1[[01]]:64 | x86_64*-*-solaris2.1[[01]]:64)
+ libgo_cv_lib_setcontext_clobbers_tls=yes ;;
+ *)
+ libgo_cv_lib_setcontext_clobbers_tls=no ;;
+ esac
+])
+CFLAGS="$CFLAGS_hold"
+LIBS="$LIBS_hold"
+])
+if test "$libgo_cv_lib_setcontext_clobbers_tls" = "yes"; then
+ AC_DEFINE(SETCONTEXT_CLOBBERS_TLS, 1,
+ [Define if setcontext clobbers TLS variables])
+fi
+