configure.ac (--enable-linux-futex): Add new configure option.

libstdc++-v3/
	* configure.ac (--enable-linux-futex): Add new configure option.
	(HAVE_LINUX_FUTEX): New AC_DEFINE.
	* Makefile.in: Rebuilt.
	* aclocal.m4: Rebuilt.
	* 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.
config/
	* futex.m4: New file.
libgomp/
	* configure.ac: Move futex checking into ../config/futex.m4.
	* configure: Rebuilt.
	* aclocal.m4: Rebuilt.
	* Makefile.in: Rebuilt.

	* configure.tgt: Rename have_tls to gcc_cv_have_tls to match
	2007-10-15 ../config/tls.m4 change.

From-SVN: r131399
This commit is contained in:
Jakub Jelinek 2008-01-08 17:14:49 +01:00 committed by Jakub Jelinek
parent c90eee444c
commit 0f3e711eef
17 changed files with 486 additions and 96 deletions

View File

@ -1,3 +1,7 @@
2008-01-08 Jakub Jelinek <jakub@redhat.com>
* futex.m4: New file.
2007-12-06 Richard Sandiford <rsandifo@nildram.co.uk>
* mt-sde (CFLAGS_FOR_TARGET, CXXFLAGS_FOR_TARGET): Use +=, not =.

64
config/futex.m4 Normal file
View File

@ -0,0 +1,64 @@
dnl ----------------------------------------------------------------------
dnl This whole bit snagged from libgomp.
dnl
dnl GCC_LINUX_FUTEX
dnl (SHELL-CODE_HANDLER)
dnl
AC_DEFUN([GCC_LINUX_FUTEX],[dnl
GCC_ENABLE(linux-futex,default, ,[use the Linux futex system call],
permit yes|no|default)
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 test x$cross_compiling = xno; then
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
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
if test x$enable_linux_futex = xyes; then
$1
fi
])

View File

@ -1,3 +1,13 @@
2008-01-08 Jakub Jelinek <jakub@redhat.com>
* configure.ac: Move futex checking into ../config/futex.m4.
* configure: Rebuilt.
* aclocal.m4: Rebuilt.
* Makefile.in: Rebuilt.
* configure.tgt: Rename have_tls to gcc_cv_have_tls to match
2007-10-15 ../config/tls.m4 change.
2007-12-19 Jakub Jelinek <jakub@redhat.com>
PR c++/34513

View File

@ -55,7 +55,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../config/lead-dot.m4 \
$(top_srcdir)/../config/multi.m4 \
$(top_srcdir)/../config/stdint.m4 \
$(top_srcdir)/../config/tls.m4 $(top_srcdir)/../ltoptions.m4 \
$(top_srcdir)/../config/tls.m4 \
$(top_srcdir)/../config/futex.m4 $(top_srcdir)/../ltoptions.m4 \
$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
$(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/../libtool.m4 $(top_srcdir)/configure.ac

1
libgomp/aclocal.m4 vendored
View File

@ -863,6 +863,7 @@ m4_include([../config/lead-dot.m4])
m4_include([../config/multi.m4])
m4_include([../config/stdint.m4])
m4_include([../config/tls.m4])
m4_include([../config/futex.m4])
m4_include([../ltoptions.m4])
m4_include([../ltsugar.m4])
m4_include([../ltversion.m4])

58
libgomp/configure vendored
View File

@ -1003,8 +1003,6 @@ Optional Features:
--enable-version-specific-runtime-libs
Specify that runtime libraries should be installed
in a compiler-specific directory [default=no]
--enable-linux-futex Use the Linux futex system call
[default=default]
--enable-generated-files-in-srcdir
put copies of generated files in source dir intended
for creating source tarballs for users without
@ -1021,6 +1019,8 @@ Optional Features:
--disable-libtool-lock avoid locking (might break parallel builds)
--enable-maintainer-mode enable make rules and dependencies not useful
(and sometimes confusing) to the casual installer
--enable-linux-futex use the Linux futex system call
[default=default]
--enable-tls Use thread-local storage [default=yes]
--enable-symvers=STYLE enables symbol versioning of the shared library
[default=yes]
@ -1518,26 +1518,6 @@ fi;
echo "$as_me:$LINENO: result: $enable_version_specific_runtime_libs" >&5
echo "${ECHO_T}$enable_version_specific_runtime_libs" >&6
echo "$as_me:$LINENO: checking for --enable-linux-futex" >&5
echo $ECHO_N "checking for --enable-linux-futex... $ECHO_C" >&6
# 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;
echo "$as_me:$LINENO: result: $enable_linux_futex" >&5
echo "${ECHO_T}$enable_linux_futex" >&6
# We would like our source tree to be readonly. However when releases or
# pre-releases are generated, the flex/bison generated files as well as the
# various formats of manuals need to be included along with the rest of the
@ -16661,6 +16641,24 @@ cat >>confdefs.h <<\_ACEOF
_ACEOF
;;
esac
# 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;
case "$target" in
*-linux*)
case "$enable_linux_futex" in
default)
@ -16709,7 +16707,9 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
cat >conftest.$ac_ext <<_ACEOF
save_LIBS="$LIBS"
LIBS="-lpthread $LIBS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@ -16757,7 +16757,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
if test x$cross_compiling = xno; then
if getconf GNU_LIBPTHREAD_VERSION 2>/dev/null \
| LC_ALL=C grep -i NPTL > /dev/null 2>/dev/null; then
| 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.
@ -16768,6 +16768,7 @@ If so, please configure with --disable-linux-futex" >&2;}
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
@ -16776,7 +16777,7 @@ fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
;;
yes)
yes)
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
@ -16829,7 +16830,14 @@ rm -f conftest.err conftest.$ac_objext \
;;
esac
;;
*)
enable_linux_futex=no
;;
esac
if test x$enable_linux_futex = xyes; then
:
fi
# Check for pthread_{,attr_}[sg]etaffinity_np.
cat >conftest.$ac_ext <<_ACEOF

View File

@ -15,12 +15,6 @@ LIBGOMP_ENABLE(version-specific-runtime-libs, no, ,
permit yes|no)
AC_MSG_RESULT($enable_version_specific_runtime_libs)
AC_MSG_CHECKING([for --enable-linux-futex])
LIBGOMP_ENABLE(linux-futex, default, ,
[Use the Linux futex system call],
permit yes|no|default)
AC_MSG_RESULT($enable_linux_futex)
# We would like our source tree to be readonly. However when releases or
# pre-releases are generated, the flex/bison generated files as well as the
# various formats of manuals need to be included along with the rest of the
@ -192,50 +186,10 @@ case "$host" in
AC_DEFINE(HAVE_BROKEN_POSIX_SEMAPHORES, 1,
Define if the POSIX Semaphores do not work on your system.)
;;
*-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);])],
[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 test x$cross_compiling = xno; then
if getconf GNU_LIBPTHREAD_VERSION 2>/dev/null \
| LC_ALL=C grep -i NPTL > /dev/null 2>/dev/null; then
AC_MSG_WARN([The kernel might not support futex or gettid syscalls.
If so, please configure with --disable-linux-futex])
fi
fi
enable_linux_futex=yes])])
;;
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
;;
esac
GCC_LINUX_FUTEX(:)
# Check for pthread_{,attr_}[sg]etaffinity_np.
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(

View File

@ -11,7 +11,7 @@
# XLDFLAGS Add extra link flags to use.
# Optimize TLS usage by avoiding the overhead of dynamic allocation.
if test $have_tls = yes ; then
if test $gcc_cv_have_tls = yes ; then
case "${target}" in
*-*-linux*)

View File

@ -1,3 +1,23 @@
2008-01-08 Jakub Jelinek <jakub@redhat.com>
* configure.ac (--enable-linux-futex): Add new configure option.
(HAVE_LINUX_FUTEX): New AC_DEFINE.
* Makefile.in: Rebuilt.
* aclocal.m4: Rebuilt.
* 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.
2008-01-07 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/34680

View File

@ -54,6 +54,7 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \
$(top_srcdir)/../config/multi.m4 \
$(top_srcdir)/../config/no-executables.m4 \
$(top_srcdir)/../config/unwind_ipinfo.m4 \
$(top_srcdir)/../config/futex.m4 \
$(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
$(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
$(top_srcdir)/crossconfig.m4 $(top_srcdir)/linkage.m4 \

View File

@ -589,6 +589,7 @@ m4_include([../config/lib-prefix.m4])
m4_include([../config/multi.m4])
m4_include([../config/no-executables.m4])
m4_include([../config/unwind_ipinfo.m4])
m4_include([../config/futex.m4])
m4_include([../libtool.m4])
m4_include([../ltoptions.m4])
m4_include([../ltsugar.m4])

View File

@ -232,6 +232,9 @@
/* Only used in build directory testsuite_hooks.h. */
#undef HAVE_LIMIT_VMEM
/* Define if futex syscall is available. */
#undef HAVE_LINUX_FUTEX
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H

View File

@ -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 (2, 1)
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 (2, 1)
__extension__ typedef int __guard __attribute__((mode (__DI__)));
// __cxa_vec_ctor has void return type.

View File

@ -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 (2, 1)
__extension__ typedef int __guard __attribute__((mode (__DI__)));
// __cxa_vec_ctor has void return type.

216
libstdc++-v3/configure vendored
View File

@ -1053,6 +1053,8 @@ Optional Features:
memory [default=no]
--enable-tls Use thread-local storage [default=yes]
--disable-rpath do not hardcode runtime library paths
--enable-linux-futex use the Linux futex system call
[default=default]
--enable-symvers=STYLE enables symbol versioning of the shared library
[default=yes]
--enable-visibility enables visibility safe usage [default=yes]
@ -114116,8 +114118,222 @@ _ACEOF
#define HAVE_GETIPINFO 1
_ACEOF
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;
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 test x$cross_compiling = xno; then
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
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
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.

View File

@ -295,9 +295,10 @@ else
# Assume we have _Unwind_GetIPInfo for cross-compiles.
AC_DEFINE(HAVE_GETIPINFO)
fi
GCC_LINUX_FUTEX([AC_DEFINE(HAVE_LINUX_FUTEX, 1, [Define if futex syscall is available.])])
# This depends on GLIBCXX CHECK_LINKER_FEATURES, but without it assumes no.
GLIBCXX_ENABLE_SYMVERS([yes])
GLIBCXX_ENABLE_VISIBILITY([yes])

View File

@ -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 *g)
_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,20 @@ 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 waiting_bit = _GLIBCXX_GUARD_WAITING_BIT;
int old = __sync_lock_test_and_set (gi, 0);
if ((old & waiting_bit) != 0)
syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAKE, INT_MAX);
return;
}
#elif defined(__GTHREAD_HAS_COND)
if (__gthread_active_p())
{
mutex_wrapper mw;
@ -293,7 +376,21 @@ 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 waiting_bit = _GLIBCXX_GUARD_WAITING_BIT;
int old = __sync_lock_test_and_set (gi, guard_bit);
if ((old & waiting_bit) != 0)
syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAKE, INT_MAX);
return;
}
#elif defined(__GTHREAD_HAS_COND)
if (__gthread_active_p())
{
mutex_wrapper mw;