This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Optimized __cxa_guard_{acquire,release,abort} for Linux


On Mon, Dec 31, 2007 at 05:06:41PM +0100, Paolo Carlini wrote:
> Richard Guenther wrote:
> > This would also "fix" PR33960, right?  So at least for me it would be

Yes.

> > worthwhile to
> > do for 4.3 ;)
> >   
> Thanks Richard for your feedback. My first impression (while I cannot
> say I understand all the technical details of the approach) is also very
> good. I would suggest working on the configury bits, while waiting for
> more feedback.

Here is the patch together with the configure bits.  For native build
when neither --{enable,disable}-linux-futex is given the same rules as
in libgomp configury are used, --enable-linux-futex enables it
unconditionally (and errors if SYS_futex isn't defined in headers),
--disable-linux-futex disables it.  For cross only explicit
--enable-linux-futex will enable it, as we shouldn't do link tests.

2008-01-02  Jakub Jelinek  <jakub@redhat.com>

	* configure.ac (--enable-linux-futex): Add new configure option.
	(HAVE_LINUX_FUTEX): New AC_DEFINE.
	* configure: Rebuilt.
	* config.h.in: Rebuilt.
	* config/cpu/generic/cxxabi_tweaks.h (_GLIBCXX_GUARD_BIT,
	_GLIBCXX_GUARD_PENDING_BIT, _GLIBCXX_GUARD_WAITING_BIT): Define.
	* config/cpu/arm/cxxabi_tweaks.h (_GLIBCXX_GUARD_BIT,
	_GLIBCXX_GUARD_PENDING_BIT, _GLIBCXX_GUARD_WAITING_BIT): Define.
	* libsupc++/guard.cc: Include climits and syscall.h.
	(_GLIBCXX_USE_FUTEX): Define if futex syscall and atomic builtins
	are supported.
	(_GLIBCXX_FUTEX_WAIT, _GLIBCXX_FUTEX_WAKE): Likewise.
	(__guard_test_bit): New static inline.
	(__cxa_guard_acquire, __cxa_guard_release, __cxa_guard_abort): Use
	atomic builtins and futex syscall if _GLIBCXX_USE_FUTEX.

--- libstdc++-v3/config/cpu/arm/cxxabi_tweaks.h.jj	2007-12-31 20:55:23.000000000 +0100
+++ libstdc++-v3/config/cpu/arm/cxxabi_tweaks.h	2008-01-02 10:23:32.000000000 +0100
@@ -1,6 +1,6 @@
 // Control various target specific ABI tweaks.  ARM version.
 
-// Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2006, 2008 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -46,6 +46,9 @@ namespace __cxxabiv1
   // guard variable.  */
 #define _GLIBCXX_GUARD_TEST(x) ((*(x) & 1) != 0)
 #define _GLIBCXX_GUARD_SET(x) *(x) = 1
+#define _GLIBCXX_GUARD_BIT 1
+#define _GLIBCXX_GUARD_PENDING_BIT __guard_test_bit (1, 1)
+#define _GLIBCXX_GUARD_WAITING_BIT __guard_test_bit (1, 2)
   typedef int __guard;
 
   // We also want the element size in array cookies.
@@ -62,6 +65,9 @@ namespace __cxxabiv1
   // The generic ABI uses the first byte of a 64-bit guard variable.
 #define _GLIBCXX_GUARD_TEST(x) (*(char *) (x) != 0)
 #define _GLIBCXX_GUARD_SET(x) *(char *) (x) = 1
+#define _GLIBCXX_GUARD_BIT __guard_test_bit (0, 1)
+#define _GLIBCXX_GUARD_PENDING_BIT __guard_test_bit (1, 1)
+#define _GLIBCXX_GUARD_WAITING_BIT __guard_test_bit (1, 2)
   __extension__ typedef int __guard __attribute__((mode (__DI__)));
 
   // __cxa_vec_ctor has void return type.
--- libstdc++-v3/config/cpu/generic/cxxabi_tweaks.h.jj	2007-12-31 20:55:23.000000000 +0100
+++ libstdc++-v3/config/cpu/generic/cxxabi_tweaks.h	2008-01-02 10:23:32.000000000 +0100
@@ -1,6 +1,6 @@
 // Control various target specific ABI tweaks.  Generic version.
 
-// Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2006, 2008 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -44,6 +44,9 @@ namespace __cxxabiv1
   // The generic ABI uses the first byte of a 64-bit guard variable.
 #define _GLIBCXX_GUARD_TEST(x) (*(char *) (x) != 0)
 #define _GLIBCXX_GUARD_SET(x) *(char *) (x) = 1
+#define _GLIBCXX_GUARD_BIT __guard_test_bit (0, 1)
+#define _GLIBCXX_GUARD_PENDING_BIT __guard_test_bit (1, 1)
+#define _GLIBCXX_GUARD_WAITING_BIT __guard_test_bit (1, 2)
   __extension__ typedef int __guard __attribute__((mode (__DI__)));
 
   // __cxa_vec_ctor has void return type.
--- libstdc++-v3/libsupc++/guard.cc.jj	2007-12-31 20:55:22.000000000 +0100
+++ libstdc++-v3/libsupc++/guard.cc	2008-01-02 11:15:04.000000000 +0100
@@ -35,12 +35,21 @@
 #include <new>
 #include <ext/atomicity.h>
 #include <ext/concurrence.h>
+#if defined(__GTHREADS) && defined(__GTHREAD_HAS_COND) \
+    && defined(_GLIBCXX_ATOMIC_BUILTINS) && defined(_GLIBCXX_HAVE_LINUX_FUTEX)
+# include <climits>
+# include <syscall.h>
+# define _GLIBCXX_USE_FUTEX
+# define _GLIBCXX_FUTEX_WAIT 0
+# define _GLIBCXX_FUTEX_WAKE 1
+#endif
 
 // The IA64/generic ABI uses the first byte of the guard variable.
 // The ARM EABI uses the least significant bit.
 
 // Thread-safe static local initialization support.
 #ifdef __GTHREADS
+# ifndef _GLIBCXX_USE_FUTEX
 namespace
 {
   // A single mutex controlling all static initializations.
@@ -75,8 +84,9 @@ namespace
     }
   };
 }
+# endif
 
-#ifdef __GTHREAD_HAS_COND
+# if defined(__GTHREAD_HAS_COND) && !defined(_GLIBCXX_USE_FUTEX)
 namespace
 {
   // A single conditional variable controlling all static initializations.
@@ -98,9 +108,9 @@ namespace
     return *static_cond;
   }
 }
-#endif
+# endif
 
-#ifndef _GLIBCXX_GUARD_TEST_AND_ACQUIRE
+# ifndef _GLIBCXX_GUARD_TEST_AND_ACQUIRE
 inline bool
 __test_and_acquire (__cxxabiv1::__guard *g)
 {
@@ -108,24 +118,24 @@ __test_and_acquire (__cxxabiv1::__guard 
   _GLIBCXX_READ_MEM_BARRIER;
   return b;
 }
-#define _GLIBCXX_GUARD_TEST_AND_ACQUIRE(G) __test_and_acquire (G)
-#endif
+#  define _GLIBCXX_GUARD_TEST_AND_ACQUIRE(G) __test_and_acquire (G)
+# endif
 
-#ifndef _GLIBCXX_GUARD_SET_AND_RELEASE
+# ifndef _GLIBCXX_GUARD_SET_AND_RELEASE
 inline void
 __set_and_release (__cxxabiv1::__guard *g)
 {
   _GLIBCXX_WRITE_MEM_BARRIER;
   _GLIBCXX_GUARD_SET (g);
 }
-#define _GLIBCXX_GUARD_SET_AND_RELEASE(G) __set_and_release (G)
-#endif
+#  define _GLIBCXX_GUARD_SET_AND_RELEASE(G) __set_and_release (G)
+# endif
 
 #else /* !__GTHREADS */
 
-#undef _GLIBCXX_GUARD_TEST_AND_ACQUIRE
-#undef _GLIBCXX_GUARD_SET_AND_RELEASE
-#define _GLIBCXX_GUARD_SET_AND_RELEASE(G) _GLIBCXX_GUARD_SET (G)
+# undef _GLIBCXX_GUARD_TEST_AND_ACQUIRE
+# undef _GLIBCXX_GUARD_SET_AND_RELEASE
+# define _GLIBCXX_GUARD_SET_AND_RELEASE(G) _GLIBCXX_GUARD_SET (G)
 
 #endif /* __GTHREADS */
 
@@ -176,8 +186,35 @@ namespace __gnu_cxx
 // headers define a symbol __GTHREAD_HAS_COND for platforms that support POSIX
 // like conditional variables. For platforms that do not support conditional
 // variables, we need to fall back to the old code.
+
+// If _GLIBCXX_USE_FUTEX, no global mutex or conditional variable is used,
+// only atomic operations are used together with futex syscall.
+// Valid values of the first integer in guard are:
+// 0				  No thread encountered the guarded init
+//				  yet or it has been aborted.
+// _GLIBCXX_GUARD_BIT		  The guarded static var has been successfully
+//				  initialized.
+// _GLIBCXX_GUARD_PENDING_BIT	  The guarded static var is being initialized
+//				  and no other thread is waiting for its
+//				  initialization.
+// (_GLIBCXX_GUARD_PENDING_BIT    The guarded static var is being initialized
+//  | _GLIBCXX_GUARD_WAITING_BIT) and some other threads are waiting until
+//				  it is initialized.
+
 namespace __cxxabiv1 
 {
+#ifdef _GLIBCXX_USE_FUTEX
+  namespace
+  {
+    static inline int __guard_test_bit (const int __byte, const int __val)
+    {
+      union { int __i; char __c[sizeof (int)]; } __u = { 0 };
+      __u.__c[__byte] = __val;
+      return __u.__i;
+    }
+  }
+#endif
+
   static inline int
   init_in_progress_flag(__guard* g)
   { return ((char *)g)[1]; }
@@ -207,7 +244,7 @@ namespace __cxxabiv1 
       return 0;
 
     if (init_in_progress_flag(g))
-	throw_recursive_init_exception();
+      throw_recursive_init_exception();
 
     set_init_in_progress_flag(g, 1);
     return 1;
@@ -223,14 +260,46 @@ namespace __cxxabiv1 
     if (_GLIBCXX_GUARD_TEST_AND_ACQUIRE (g))
       return 0;
 
+# ifdef _GLIBCXX_USE_FUTEX
+    // If __sync_* and futex syscall are supported, don't use any global
+    // mutex.
+    if (__gthread_active_p ())
+      {
+	int *gi = (int *) (void *) g;
+	const int guard_bit = _GLIBCXX_GUARD_BIT;
+	const int pending_bit = _GLIBCXX_GUARD_PENDING_BIT;
+	const int waiting_bit = _GLIBCXX_GUARD_WAITING_BIT;
+
+	while (1)
+	  {
+	    int old = __sync_val_compare_and_swap (gi, 0, pending_bit);
+	    if (old == 0)
+	      return 1;	// This thread should do the initialization.
+
+	    if (old == guard_bit)
+	      return 0;	// Already initialized.
+
+	    if (old == pending_bit)
+	      {
+		int newv = old | waiting_bit;
+		if (__sync_val_compare_and_swap (gi, old, newv) != old)
+		  continue;
+
+		old = newv;
+	      }
+
+	    syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAIT, old, 0);
+	  }
+      }
+# else
     if (__gthread_active_p ())
       {
 	mutex_wrapper mw;
 
 	while (1)	// When this loop is executing, mutex is locked.
 	  {
-#ifdef __GTHREAD_HAS_COND
-	    // The static is allready initialized.
+#  ifdef __GTHREAD_HAS_COND
+	    // The static is already initialized.
 	    if (_GLIBCXX_GUARD_TEST(g))
 	      return 0;	// The mutex will be unlocked via wrapper
 
@@ -247,7 +316,7 @@ namespace __cxxabiv1 
 		set_init_in_progress_flag(g, 1);
 		return 1; // The mutex will be unlocked via wrapper.
 	      }
-#else
+#  else
 	    // This provides compatibility with older systems not supporting
 	    // POSIX like conditional variables.
 	    if (acquire(g))
@@ -256,9 +325,10 @@ namespace __cxxabiv1 
 		return 1; // The mutex still locked.
 	      }
 	    return 0; // The mutex will be unlocked via wrapper.
-#endif
+#  endif
 	  }
       }
+# endif
 #endif
 
     return acquire (g);
@@ -267,7 +337,35 @@ namespace __cxxabiv1 
   extern "C"
   void __cxa_guard_abort (__guard *g)
   {
-#ifdef __GTHREAD_HAS_COND
+#ifdef _GLIBCXX_USE_FUTEX
+    // If __sync_* and futex syscall are supported, don't use any global
+    // mutex.
+    if (__gthread_active_p ())
+      {
+	int *gi = (int *) (void *) g;
+	const int pending_bit = _GLIBCXX_GUARD_PENDING_BIT;
+	const int waiting_bit = _GLIBCXX_GUARD_WAITING_BIT;
+	int old;
+
+	old = __sync_val_compare_and_swap (gi, pending_bit, 0);
+	if (old == (pending_bit | waiting_bit))
+	  {
+	    while (1)
+	      {
+		int newv = old & ~(pending_bit | waiting_bit);
+		int oldv = __sync_val_compare_and_swap (gi, old, newv);
+
+		if (oldv == old)
+		  break;
+		if ((oldv & pending_bit) == 0)
+		  break;
+		old = oldv;
+	      }
+	    syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAKE, INT_MAX);
+	  }
+	return;
+      }
+#elif defined(__GTHREAD_HAS_COND)
     if (__gthread_active_p())
       {	
 	mutex_wrapper mw;
@@ -293,7 +391,33 @@ namespace __cxxabiv1 
   extern "C"
   void __cxa_guard_release (__guard *g)
   {
-#ifdef __GTHREAD_HAS_COND
+#ifdef _GLIBCXX_USE_FUTEX
+    // If __sync_* and futex syscall are supported, don't use any global
+    // mutex.
+    if (__gthread_active_p ())
+      {
+	int *gi = (int *) (void *) g;
+	const int guard_bit = _GLIBCXX_GUARD_BIT;
+	const int pending_bit = _GLIBCXX_GUARD_PENDING_BIT;
+	const int waiting_bit = _GLIBCXX_GUARD_WAITING_BIT;
+	int old;
+
+	old = __sync_val_compare_and_swap (gi, pending_bit, guard_bit);
+	if (old == (pending_bit | waiting_bit))
+	  {
+	    while (1)
+	      {
+		int oldv = __sync_val_compare_and_swap (gi, old, guard_bit);
+
+		if (oldv == old || oldv == guard_bit)
+		  break;
+		old = oldv;
+	      }
+	    syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAKE, INT_MAX);
+	  }
+	return;
+      }
+#elif defined(__GTHREAD_HAS_COND)
     if (__gthread_active_p())
       {
 	mutex_wrapper mw;
--- libstdc++-v3/configure.ac.jj	2007-09-14 11:54:41.000000000 +0200
+++ libstdc++-v3/configure.ac	2008-01-02 11:04:42.000000000 +0100
@@ -128,6 +128,9 @@ if test $atomicity_dir = cpu/generic/ato
   fi
 fi
 
+GLIBCXX_ENABLE(linux-futex,default, ,[use the Linux futex system call],
+	       permit yes|no|default)
+
 GLIBCXX_CHECK_COMPILER_FEATURES
 
 if $GLIBCXX_IS_NATIVE; then
@@ -188,6 +191,55 @@ if $GLIBCXX_IS_NATIVE; then
   # For iconv support.
   AM_ICONV
 
+  case "$target" in
+    *-linux*)
+      case "$enable_linux_futex" in
+        default)
+	  # If headers don't have gettid/futex syscalls definition, then
+	  # default to no, otherwise there will be compile time failures.
+	  # Otherwise, default to yes.  If we don't detect we are
+	  # compiled/linked against NPTL and not cross-compiling, check
+	  # if programs are run by default against NPTL and if not, issue
+	  # a warning.
+	  enable_linux_futex=no
+	  AC_LINK_IFELSE(
+	   [AC_LANG_PROGRAM(
+	    [#include <sys/syscall.h>
+	     int lk;],
+	    [syscall (SYS_gettid); syscall (SYS_futex, &lk, 0, 0, 0);])],
+	    [save_LIBS="$LIBS"
+	     LIBS="-lpthread $LIBS"
+	     AC_LINK_IFELSE(
+	     [AC_LANG_PROGRAM(
+	      [#ifndef _GNU_SOURCE
+	       #define _GNU_SOURCE 1
+	       #endif
+	       #include <pthread.h>
+	       pthread_t th; void *status;],
+	      [pthread_tryjoin_np (th, &status);])],[enable_linux_futex=yes],
+	      [if getconf GNU_LIBPTHREAD_VERSION 2>/dev/null \
+		  | LC_ALL=C grep -i NPTL > /dev/null 2>/dev/null; then :; else
+		 AC_MSG_WARN([The kernel might not support futex or gettid syscalls.
+If so, please configure with --disable-linux-futex])
+	       fi
+	       enable_linux_futex=yes])
+	     LIBS="$save_LIBS"])
+	  ;;
+        yes)
+	  AC_LINK_IFELSE(
+	   [AC_LANG_PROGRAM(
+	    [#include <sys/syscall.h>
+	     int lk;],
+	    [syscall (SYS_gettid); syscall (SYS_futex, &lk, 0, 0, 0);])],[],
+	    [AC_MSG_ERROR([SYS_gettid and SYS_futex required for --enable-linux-futex])])
+	  ;;
+      esac
+      ;;
+    *)
+      enable_linux_futex=no
+      ;;
+  esac
+
 else
 
   # This lets us hard-code the functionality we know we'll have in the cross
@@ -296,6 +348,31 @@ else
   # Assume we have _Unwind_GetIPInfo for cross-compiles.
   AC_DEFINE(HAVE_GETIPINFO)
 
+  case "$target" in
+    *-linux*)
+      case "$enable_linux_futex" in
+        yes)
+	  AC_COMPILE_IFELSE(
+	   [AC_LANG_PROGRAM(
+	    [#include <sys/syscall.h>
+	     int lk;],
+	    [syscall (SYS_gettid); syscall (SYS_futex, &lk, 0, 0, 0);])],[],
+	    [AC_MSG_ERROR([SYS_gettid and SYS_futex required for --enable-linux-futex])])
+	  ;;
+	*)
+	  enable_linux_futex=no
+	  ;;
+      esac
+      ;;
+    *)
+      enable_linux_futex=no
+      ;;
+  esac
+
+fi
+
+if test x$enable_linux_futex = xyes; then
+  AC_DEFINE(HAVE_LINUX_FUTEX, 1, [Define if futex syscall is available.])
 fi
 
 # This depends on GLIBCXX CHECK_LINKER_FEATURES, but without it assumes no.
--- libstdc++-v3/configure.jj	2007-11-10 01:15:03.000000000 +0100
+++ libstdc++-v3/configure	2008-01-02 11:04:54.000000000 +0100
@@ -1051,6 +1051,8 @@ Optional Features:
   --enable-fully-dynamic-string
                           do not put empty strings in per-process static
                           memory [default=no]
+  --enable-linux-futex    use the Linux futex system call
+                          [default=default]
   --enable-tls            Use thread-local storage [default=yes]
   --disable-rpath         do not hardcode runtime library paths
   --enable-symvers=STYLE  enables symbol versioning of the shared library
@@ -17848,6 +17850,22 @@ echo "$as_me: WARNING: Performance of ce
   fi
 fi
 
+ # Check whether --enable-linux-futex or --disable-linux-futex was given.
+if test "${enable_linux_futex+set}" = set; then
+  enableval="$enable_linux_futex"
+
+      case "$enableval" in
+       yes|no|default) ;;
+       *) { { echo "$as_me:$LINENO: error: Unknown argument to enable/disable linux-futex" >&5
+echo "$as_me: error: Unknown argument to enable/disable linux-futex" >&2;}
+   { (exit 1); exit 1; }; } ;;
+                          esac
+
+else
+  enable_linux_futex=default
+fi;
+
+
 
   # All these tests are for C++; save the language and the compiler flags.
   # The CXXFLAGS thing is suspicious, but based on similar bits previously
@@ -42519,6 +42537,196 @@ _ACEOF
   fi
 
 
+  case "$target" in
+    *-linux*)
+      case "$enable_linux_futex" in
+        default)
+	  # If headers don't have gettid/futex syscalls definition, then
+	  # default to no, otherwise there will be compile time failures.
+	  # Otherwise, default to yes.  If we don't detect we are
+	  # compiled/linked against NPTL and not cross-compiling, check
+	  # if programs are run by default against NPTL and if not, issue
+	  # a warning.
+	  enable_linux_futex=no
+	  if test x$gcc_no_link = xyes; then
+  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/syscall.h>
+	     int lk;
+int
+main ()
+{
+syscall (SYS_gettid); syscall (SYS_futex, &lk, 0, 0, 0);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  save_LIBS="$LIBS"
+	     LIBS="-lpthread $LIBS"
+	     if test x$gcc_no_link = xyes; then
+  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifndef _GNU_SOURCE
+	       #define _GNU_SOURCE 1
+	       #endif
+	       #include <pthread.h>
+	       pthread_t th; void *status;
+int
+main ()
+{
+pthread_tryjoin_np (th, &status);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  enable_linux_futex=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+if getconf GNU_LIBPTHREAD_VERSION 2>/dev/null \
+		  | LC_ALL=C grep -i NPTL > /dev/null 2>/dev/null; then :; else
+		 { echo "$as_me:$LINENO: WARNING: The kernel might not support futex or gettid syscalls.
+If so, please configure with --disable-linux-futex" >&5
+echo "$as_me: WARNING: The kernel might not support futex or gettid syscalls.
+If so, please configure with --disable-linux-futex" >&2;}
+	       fi
+	       enable_linux_futex=yes
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+	     LIBS="$save_LIBS"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+	  ;;
+        yes)
+	  if test x$gcc_no_link = xyes; then
+  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/syscall.h>
+	     int lk;
+int
+main ()
+{
+syscall (SYS_gettid); syscall (SYS_futex, &lk, 0, 0, 0);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: SYS_gettid and SYS_futex required for --enable-linux-futex" >&5
+echo "$as_me: error: SYS_gettid and SYS_futex required for --enable-linux-futex" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+	  ;;
+      esac
+      ;;
+    *)
+      enable_linux_futex=no
+      ;;
+  esac
+
 else
 
   # This lets us hard-code the functionality we know we'll have in the cross
@@ -114117,6 +114325,77 @@ _ACEOF
 _ACEOF
 
 
+  case "$target" in
+    *-linux*)
+      case "$enable_linux_futex" in
+        yes)
+	  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/syscall.h>
+	     int lk;
+int
+main ()
+{
+syscall (SYS_gettid); syscall (SYS_futex, &lk, 0, 0, 0);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: SYS_gettid and SYS_futex required for --enable-linux-futex" >&5
+echo "$as_me: error: SYS_gettid and SYS_futex required for --enable-linux-futex" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+	  ;;
+	*)
+	  enable_linux_futex=no
+	  ;;
+      esac
+      ;;
+    *)
+      enable_linux_futex=no
+      ;;
+  esac
+
+fi
+
+if test x$enable_linux_futex = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LINUX_FUTEX 1
+_ACEOF
+
 fi
 
 # This depends on GLIBCXX CHECK_LINKER_FEATURES, but without it assumes no.
--- libstdc++-v3/config.h.in.jj	2007-10-19 14:39:59.000000000 +0200
+++ libstdc++-v3/config.h.in	2008-01-02 11:04:27.000000000 +0100
@@ -719,6 +719,9 @@
 /* Define if a fully dynamic basic_string is wanted. */
 #undef _GLIBCXX_FULLY_DYNAMIC_STRING
 
+/* Define if futex syscall is available. */
+#undef HAVE_LINUX_FUTEX
+
 /* Define to 1 if a full hosted library is built, or 0 if freestanding. */
 #undef _GLIBCXX_HOSTED
 


	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]