* [v3] define std::thread::hardware_concurrency()
@ 2011-05-28 12:50 Jonathan Wakely
2011-05-29 9:04 ` Jonathan Wakely
0 siblings, 1 reply; 2+ messages in thread
From: Jonathan Wakely @ 2011-05-28 12:50 UTC (permalink / raw)
To: libstdc++, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1064 bytes --]
This patch uses glibc's get_nprocs() or the non-standard but widely
available _SC_NPROCESSORS_ONLN sysconf variable to determine the
number of processors.
2011-05-28 Jonathan Wakely <jwakely.gcc@gmail.com>
* acinclude.m4: Define GLIBCXX_CHECK_GET_NPROCS and
GLIBCXX_CHECK_SC_NPROCESSORS_ONLN.
* configure.ac: Use them. Increase minor version.
* configure: Regenerate.
* config.h.in: Regenerate.
* include/std/thread (thread::hardware_concurrency): Remove inline
definition.
* src/thread.cc (thread::hardware_concurrency): Define.
* config/abi/pre/gnu.ver: Export new symbol @3.4.17
* testsuite/util/testsuite_abi.cc: Add new version.
* testsuite/lib/libstdc++.exp (check_v3_target_nprocs): Add.
* testsuite/lib/dg-options.exp (dg-require-nprocs): Add.
* testsuite/30_threads/thread/members/hardware_concurrency.cc: Use
dg-require-nprocs and verify hardware_concurrency returns non-zero.
Tested x86_64-linux, I intend to commit to trunk tomorrow.
[-- Attachment #2: hwconc.txt --]
[-- Type: text/plain, Size: 8496 bytes --]
Index: acinclude.m4
===================================================================
--- acinclude.m4 (revision 174307)
+++ acinclude.m4 (working copy)
@@ -3204,6 +3204,61 @@
])
])
+dnl
+dnl Check whether get_nprocs is available in <sys/sysinfo.h>, 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 <sys/sysinfo.h>],
+ [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 <sys/sysinfo.h>.])
+ fi
+ AC_MSG_RESULT($glibcxx_cv_GET_NPROCS)
+
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ AC_LANG_RESTORE
+])
+
+dnl
+dnl Check whether sysconf is available in <unistd.h>, 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 <unistd.h>],
+ [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 <unistd.h>.])
+ 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 <thread>
#include <cerrno>
+#if defined(_GLIBCXX_USE_GET_NPROCS)
+# include <sys/sysinfo.h>
+# define _GLIBCXX_NPROCS get_nprocs()
+#elif defined(_GLIBCXX_USE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
+# include <unistd.h>
+# 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 <bits/c++config.h>"
+ puts $f "#if defined(_GLIBCXX_USE_GET_NPROCS)"
+ puts $f "#elif defined(_GLIBCXX_USE_SYSCONF)"
+ puts $f "# include <unistd.h>"
+ 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;
}
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [v3] define std::thread::hardware_concurrency()
2011-05-28 12:50 [v3] define std::thread::hardware_concurrency() Jonathan Wakely
@ 2011-05-29 9:04 ` Jonathan Wakely
0 siblings, 0 replies; 2+ messages in thread
From: Jonathan Wakely @ 2011-05-29 9:04 UTC (permalink / raw)
To: libstdc++, gcc-patches
On 28 May 2011 01:43, Jonathan Wakely wrote:
> This patch uses glibc's get_nprocs() or the non-standard but widely
> available _SC_NPROCESSORS_ONLN sysconf variable to determine the
> number of processors.
>
> 2011-05-28 Jonathan Wakely <jwakely.gcc@gmail.com>
>
> * acinclude.m4: Define GLIBCXX_CHECK_GET_NPROCS and
> GLIBCXX_CHECK_SC_NPROCESSORS_ONLN.
> * configure.ac: Use them. Increase minor version.
> * configure: Regenerate.
> * config.h.in: Regenerate.
> * include/std/thread (thread::hardware_concurrency): Remove inline
> definition.
> * src/thread.cc (thread::hardware_concurrency): Define.
> * config/abi/pre/gnu.ver: Export new symbol @3.4.17
> * testsuite/util/testsuite_abi.cc: Add new version.
> * testsuite/lib/libstdc++.exp (check_v3_target_nprocs): Add.
> * testsuite/lib/dg-options.exp (dg-require-nprocs): Add.
> * testsuite/30_threads/thread/members/hardware_concurrency.cc: Use
> dg-require-nprocs and verify hardware_concurrency returns non-zero.
>
>
> Tested x86_64-linux, I intend to commit to trunk tomorrow.
I've checked that patch in, so the library version on mainline is
libstdc++.so.6.0.17 now.
If my configury changes or using sysconf breaks anything I'll try to
fix it asap.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2011-05-28 17:29 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-28 12:50 [v3] define std::thread::hardware_concurrency() Jonathan Wakely
2011-05-29 9:04 ` Jonathan Wakely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).