Index: acinclude.m4 =================================================================== --- acinclude.m4 (revision 174307) +++ acinclude.m4 (working copy) @@ -3204,6 +3204,61 @@ ]) ]) +dnl +dnl Check whether get_nprocs is available in , and define _GLIBCXX_USE_GET_NPROCS. +dnl +AC_DEFUN([GLIBCXX_CHECK_GET_NPROCS], [ + + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -fno-exceptions" + + AC_MSG_CHECKING([for get_nprocs]) + AC_CACHE_VAL(glibcxx_cv_GET_NPROCS, [ + GCC_TRY_COMPILE_OR_LINK( + [#include ], + [int n = get_nprocs();], + [glibcxx_cv_GET_NPROCS=yes], + [glibcxx_cv_GET_NPROCS=no]) + ]) + if test $glibcxx_cv_GET_NPROCS = yes; then + AC_DEFINE(_GLIBCXX_USE_GET_NPROCS, 1, [Define if get_nprocs is available in .]) + fi + AC_MSG_RESULT($glibcxx_cv_GET_NPROCS) + + CXXFLAGS="$ac_save_CXXFLAGS" + AC_LANG_RESTORE +]) + +dnl +dnl Check whether sysconf is available in , and define _GLIBCXX_USE_SYSCONF. +dnl +AC_DEFUN([GLIBCXX_CHECK_SYSCONF], [ + + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -fno-exceptions" + + AC_MSG_CHECKING([for sysconf]) + AC_CACHE_VAL(glibcxx_cv_SYSCONF, [ + GCC_TRY_COMPILE_OR_LINK( + [#include ], + [int n = sysconf(_SC_ARG_MAX);], + [glibcxx_cv_SYSCONF=yes], + [glibcxx_cv_SYSCONF=no]) + ]) + if test $glibcxx_cv_SYSCONF = yes; then + AC_DEFINE(_GLIBCXX_USE_SYSCONF, 1, [Define if sysconf is available in .]) + fi + AC_MSG_RESULT($glibcxx_cv_SYSCONF) + + CXXFLAGS="$ac_save_CXXFLAGS" + AC_LANG_RESTORE +]) + + # Macros from the top-level gcc directory. m4_include([../config/gc++filt.m4]) m4_include([../config/tls.m4]) Index: configure.ac =================================================================== --- configure.ac (revision 174307) +++ configure.ac (working copy) @@ -12,7 +12,7 @@ ### am handles this now? ORIGINAL_LD_FOR_MULTILIBS=$LD # For libtool versioning info, format is CURRENT:REVISION:AGE -libtool_VERSION=6:16:0 +libtool_VERSION=6:17:0 AC_SUBST(libtool_VERSION) # Find the rest of the source tree framework. @@ -170,6 +170,10 @@ AC_LC_MESSAGES +# For hardware_concurrency +GLIBCXX_CHECK_GET_NPROCS +GLIBCXX_CHECK_SYSCONF + # Check for available headers. AC_CHECK_HEADERS([endian.h execinfo.h float.h fp.h ieeefp.h inttypes.h \ locale.h machine/endian.h machine/param.h nan.h stdint.h stdlib.h string.h \ Index: include/std/thread =================================================================== --- include/std/thread (revision 174307) +++ include/std/thread (working copy) @@ -179,8 +179,7 @@ // Returns a value that hints at the number of hardware thread contexts. static unsigned int - hardware_concurrency() noexcept - { return 0; } + hardware_concurrency() noexcept; private: void Index: src/thread.cc =================================================================== --- src/thread.cc (revision 174307) +++ src/thread.cc (working copy) @@ -26,6 +26,16 @@ #include #include +#if defined(_GLIBCXX_USE_GET_NPROCS) +# include +# define _GLIBCXX_NPROCS get_nprocs() +#elif defined(_GLIBCXX_USE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) +# include +# define _GLIBCXX_NPROCS sysconf(_SC_NPROCESSORS_ONLN) +#else +# define _GLIBCXX_NPROCS 0 +#endif + #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) namespace std _GLIBCXX_VISIBILITY(default) @@ -98,6 +108,15 @@ } } + unsigned int + thread::hardware_concurrency() noexcept + { + int __n = _GLIBCXX_NPROCS; + if (__n < 0) + __n = 0; + return __n; + } + _GLIBCXX_END_NAMESPACE_VERSION } // namespace std Index: config/abi/pre/gnu.ver =================================================================== --- config/abi/pre/gnu.ver (revision 174307) +++ config/abi/pre/gnu.ver (working copy) @@ -1279,6 +1279,13 @@ } GLIBCXX_3.4.15; +GLIBCXX_3.4.17 { + + # std::thread::hardware_concurrency + _ZNSt6thread20hardware_concurrencyEv; + +} GLIBCXX_3.4.16; + # Symbols in the support library (libsupc++) have their own tag. CXXABI_1.3 { Index: testsuite/lib/libstdc++.exp =================================================================== --- testsuite/lib/libstdc++.exp (revision 174307) +++ testsuite/lib/libstdc++.exp (working copy) @@ -1579,4 +1579,67 @@ return $et_binary_io } +proc check_v3_target_nprocs { } { + global cxxflags + global DEFAULT_CXXFLAGS + global et_nprocs + + global tool + + if { ![info exists et_nprocs_target_name] } { + set et_nprocs_target_name "" + } + + # If the target has changed since we set the cached value, clear it. + set current_target [current_target_name] + if { $current_target != $et_nprocs_target_name } { + verbose "check_v3_target_nprocs: `$et_nprocs_target_name'" 2 + set et_nprocs_target_name $current_target + if [info exists et_nprocs] { + verbose "check_v3_target_nprocs: removing cached result" 2 + unset et_nprocs + } + } + + if [info exists et_nprocs] { + verbose "check_v3_target_nprocs: using cached result" 2 + } else { + set et_nprocs 0 + + # Set up and preprocess a C++0x test program that depends + # on either get_nprocs or sysconf to be available. + set src nprocs[pid].cc + + set f [open $src "w"] + puts $f "#include " + puts $f "#if defined(_GLIBCXX_USE_GET_NPROCS)" + puts $f "#elif defined(_GLIBCXX_USE_SYSCONF)" + puts $f "# include " + puts $f "# if !defined(_SC_NPROCESSORS_ONLN)" + puts $f "# error No sysconf option" + puts $f "# endif" + puts $f "#else" + puts $f "# error No get_nprocs or sysconf" + puts $f "#endif" + close $f + + set cxxflags_saved $cxxflags + set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror" + + set lines [v3_target_compile $src /dev/null preprocess ""] + set cxxflags $cxxflags_saved + file delete $src + + if [string match "" $lines] { + # No error message, preprocess succeeded. + set et_nprocs 1 + } else { + verbose "check_v3_target_nprocs: compilation failed" 2 + } + } + verbose "check_v3_target_nprocs: $et_nprocs" 2 + return $et_nprocs +} + + set additional_prunes "" Index: testsuite/lib/dg-options.exp =================================================================== --- testsuite/lib/dg-options.exp (revision 174307) +++ testsuite/lib/dg-options.exp (working copy) @@ -179,6 +179,15 @@ return } +proc dg-require-nprocs { args } { + if { ![ check_v3_target_nprocs ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + return + } + return +} + proc add_options_for_no_pch { flags } { # This forces any generated and possibly included PCH to be invalid. return "-D__GLIBCXX__=99999999" Index: testsuite/util/testsuite_abi.cc =================================================================== --- testsuite/util/testsuite_abi.cc (revision 174307) +++ testsuite/util/testsuite_abi.cc (working copy) @@ -194,6 +194,7 @@ known_versions.push_back("GLIBCXX_3.4.14"); known_versions.push_back("GLIBCXX_3.4.15"); known_versions.push_back("GLIBCXX_3.4.16"); + known_versions.push_back("GLIBCXX_3.4.17"); known_versions.push_back("GLIBCXX_LDBL_3.4"); known_versions.push_back("GLIBCXX_LDBL_3.4.7"); known_versions.push_back("GLIBCXX_LDBL_3.4.10"); Index: testsuite/30_threads/thread/members/hardware_concurrency.cc =================================================================== --- testsuite/30_threads/thread/members/hardware_concurrency.cc (revision 174307) +++ testsuite/30_threads/thread/members/hardware_concurrency.cc (working copy) @@ -4,8 +4,9 @@ // { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } } // { dg-require-cstdint "" } // { dg-require-gthreads "" } +// { dg-require-nprocs "" } -// Copyright (C) 2009 Free Software Foundation, Inc. +// Copyright (C) 2009, 2010, 2011 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 @@ -29,8 +30,7 @@ { bool test __attribute__((unused)) = true; - // Current implementation punts on this. - VERIFY( std::thread::hardware_concurrency() == 0 ); + VERIFY( std::thread::hardware_concurrency() >= 1 ); return 0; }