diff --git a/src/engine/jam.cpp b/src/engine/jam.cpp index 08c826bdc..850b30e01 100644 --- a/src/engine/jam.cpp +++ b/src/engine/jam.cpp @@ -272,6 +272,7 @@ int main( int argc, char * * argv, char * * arg_environ ) char const * progname = argv[ 0 ]; module_t * environ_module; int is_debugger; + b2::system_info sys_info; saved_argv0 = argv[ 0 ]; @@ -362,23 +363,23 @@ int main( int argc, char * * argv, char * * arg_environ ) usage( progname ); } + /* Set default parallel jobs to match cpu threads. This can be overridden + the usual way with -jX or PARALLELISM env var. */ + globs.jobs = sys_info.cpu_thread_count(); + /* Version info. */ if ( ( s = getoptval( optv, 'v', 0 ) ) ) { out_printf( "B2 Version %s. %s.\n", VERSION, OSMINOR ); - out_printf( " Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.\n" ); - out_printf( " Copyright 2001 David Turner.\n" ); - out_printf( " Copyright 2001-2004 David Abrahams.\n" ); - out_printf( " Copyright 2002-2019 Rene Rivera.\n" ); - out_printf( " Copyright 2003-2015 Vladimir Prus.\n" ); + out_printf( " Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.\n" ); + out_printf( " Copyright 2001 David Turner.\n" ); + out_printf( " Copyright 2001-2004 David Abrahams.\n" ); + out_printf( " Copyright 2002-2019 Rene Rivera.\n" ); + out_printf( " Copyright 2003-2015 Vladimir Prus.\n" ); + out_printf( "\n DEFAULTS: jobs = %i\n", globs.jobs); return EXITOK; } - /* Set default parallel jobs to match cpu threads. This can be overridden - the usual way with -jX or PARALLELISM env var. */ - b2::system_info sys_info; - globs.jobs = sys_info.cpu_thread_count(); - /* Pick up interesting options. */ if ( ( s = getoptval( optv, 'n', 0 ) ) ) { diff --git a/src/engine/sysinfo.cpp b/src/engine/sysinfo.cpp index b5c46e1fe..2dad17f19 100644 --- a/src/engine/sysinfo.cpp +++ b/src/engine/sysinfo.cpp @@ -7,41 +7,103 @@ #include "jam.h" #include "output.h" +#include + #if defined(OS_MACOSX) #include #include #endif + #if !defined(OS_NT) #include #endif -#include +#if defined(OS_LINUX) +#define _GNU_SOURCE +#include +#undef _GNU_SOURCE +#endif b2::system_info::system_info() { } -unsigned int b2::system_info::cpu_core_count() +namespace { - if (cpu_core_count_ == 0) + unsigned int macosx_physicalcpu() { #if defined(OS_MACOSX) int out_hw_ncpu = 0; size_t len_hw_ncpu = sizeof(out_hw_ncpu); int result = ::sysctlbyname( "hw.physicalcpu", &out_hw_ncpu, &len_hw_ncpu, nullptr, 0); - if (result == 0) - { - cpu_core_count_ = out_hw_ncpu; - } - #elif defined(_SC_NPROCESSORS_CONF) - cpu_thread_count_ = ::sysconf(_SC_NPROCESSORS_CONF); + if (result == 0) return out_hw_ncpu; #endif - if (cpu_core_count_ <= 0) + return 0; + } + + unsigned int macosx_logicalcpu() + { + #if defined(OS_MACOSX) + int out_hw_ncpu = 0; + size_t len_hw_ncpu = sizeof(out_hw_ncpu); + int result = ::sysctlbyname( + "hw.logicalcpu", &out_hw_ncpu, &len_hw_ncpu, nullptr, 0); + if (result == 0) return out_hw_ncpu; + #endif + return 0; + } + + unsigned int sched_affinity_cpu_count() + { + #if defined(CPU_COUNT_S) + ::cpu_set_t cpu_set; + if (::sched_getaffinity(0, sizeof(cpu_set_t), &cpu_set) == 0) { - cpu_core_count_ = 1; + return CPU_COUNT_S(sizeof(cpu_set_t), &cpu_set); } + #endif + return 0; + } + + unsigned int sysconf_nprocs_configured() + { + #if defined(_SC_NPROCESSORS_ONLN) + return ::sysconf(_SC_NPROCESSORS_CONF); + #else + return 0; + #endif + } + + unsigned int sysconf_nprocs_online() + { + #if defined(_SC_NPROCESSORS_ONLN) + return ::sysconf(_SC_NPROCESSORS_ONLN); + #else + return 0; + #endif + } + + unsigned int std_thread_hardware_concurrency() + { + return std::thread::hardware_concurrency(); + } +} + +unsigned int b2::system_info::cpu_core_count() +{ + if (cpu_core_count_ == 0) + { + cpu_thread_count_ = macosx_physicalcpu(); + } + if (cpu_thread_count_ == 0) + { + cpu_thread_count_ = sysconf_nprocs_configured(); + } + if (cpu_core_count_ <= 0) + { + cpu_core_count_ = 1; } return cpu_core_count_; } @@ -50,24 +112,23 @@ unsigned int b2::system_info::cpu_thread_count() { if (cpu_thread_count_ == 0) { - #if defined(OS_MACOSX) - int out_hw_ncpu = 0; - size_t len_hw_ncpu = sizeof(out_hw_ncpu); - int result = ::sysctlbyname( - "hw.logicalcpu", &out_hw_ncpu, &len_hw_ncpu, nullptr, 0); - if (result == 0) - { - cpu_thread_count_ = out_hw_ncpu; - } - #elif defined(_SC_NPROCESSORS_ONLN) - cpu_thread_count_ = ::sysconf(_SC_NPROCESSORS_ONLN); - #else - cpu_thread_count_ = std::thread::hardware_concurrency(); - #endif - if (cpu_thread_count_ <= 0) - { - cpu_thread_count_ = cpu_core_count(); - } + cpu_thread_count_ = macosx_logicalcpu(); + } + if (cpu_thread_count_ == 0) + { + cpu_thread_count_ = sched_affinity_cpu_count(); + } + if (cpu_thread_count_ == 0) + { + cpu_thread_count_ = sysconf_nprocs_online(); + } + if (cpu_thread_count_ == 0) + { + cpu_thread_count_ = std_thread_hardware_concurrency(); + } + if (cpu_thread_count_ == 0) + { + cpu_thread_count_ = cpu_core_count(); } return cpu_thread_count_; }