From d3961b8ed4945c63e6b72c887b68fc543ef72e0e Mon Sep 17 00:00:00 2001 From: "Jeroen T. Vermeulen" Date: Sun, 18 Sep 2016 21:10:28 +0200 Subject: [PATCH] Replace cpucount.c with cpucount.cpp. Uses a new function in C++11. Avoids platform-specific code. --- tools/cpucount.c | 103 ----------------------------------------- tools/cpucount.cpp | 11 +++++ tools/get_cpu_count.sh | 35 ++++++++++++-- 3 files changed, 41 insertions(+), 108 deletions(-) delete mode 100644 tools/cpucount.c create mode 100644 tools/cpucount.cpp diff --git a/tools/cpucount.c b/tools/cpucount.c deleted file mode 100644 index 3f06b8b..0000000 --- a/tools/cpucount.c +++ /dev/null @@ -1,103 +0,0 @@ -/*********************************************************************** - * OSXCross * - * Copyright (C) 2013-2016 by Thomas Poechtrager * - * t.poechtrager@gmail.com * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License * - * as published by the Free Software Foundation; either version 2 * - * of the License, or (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the Free Software * - * Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - ***********************************************************************/ - -#include -#include - -#ifdef __CYGWIN__ -#define WIN32 -#endif /* __CYGWIN__ */ - -#ifdef WIN32 -#include -#endif /* WIN32 */ - -#ifdef __linux__ -#define __USE_GNU -#include -#undef __USE_GNU -#endif /* __linux__ */ - -#if defined(__FreeBSD__) || defined(__NetBSD__) || \ - defined(__OpenBSD__) || defined(__DragonFly__) || \ - defined(__APPLE__) -#include -#include -#include -#include - -#ifndef HW_AVAILCPU -#define HW_AVAILCPU 25 -#endif /* HW_AVAILCPU */ -#endif /* BSD */ - -int getcpucount() { -#ifdef WIN32 - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - - return sysinfo.dwNumberOfProcessors; -#else -#ifdef __linux__ - cpu_set_t cs; - int i, cpucount = 0; - - CPU_ZERO(&cs); - - if (sched_getaffinity(0, sizeof(cs), &cs)) - return 1; - - for (i = 0; i < CPU_SETSIZE; i++) - if (CPU_ISSET(i, &cs)) - cpucount++; - - return cpucount; -#else -#if defined(__FreeBSD__) || defined(__NetBSD__) || \ - defined(__OpenBSD__) || defined(__DragonFly__) || \ - defined(__APPLE__) - int cpucount = 0; - int mib[4]; - size_t len = sizeof(cpucount); - - mib[0] = CTL_HW; - mib[1] = HW_AVAILCPU; - - sysctl(mib, 2, &cpucount, &len, NULL, 0); - - if (cpucount < 1) { - mib[1] = HW_NCPU; - sysctl(mib, 2, &cpucount, &len, NULL, 0); - } - - return cpucount ? cpucount : 1; -#else -#warning unknown platform - return 1; -#endif /* BSD */ -#endif /* __linux__ */ -#endif /* WIN32 */ -} - -int main(void) { - printf("%d\n", getcpucount()); - return 0; -} diff --git a/tools/cpucount.cpp b/tools/cpucount.cpp new file mode 100644 index 0000000..91c2343 --- /dev/null +++ b/tools/cpucount.cpp @@ -0,0 +1,11 @@ +#include +#include + +/** Print number of (enabled) CPU cores. + * + * Requires C++11 or better. + */ +int main() +{ + std::cout << std::thread::hardware_concurrency() << std::endl; +} diff --git a/tools/get_cpu_count.sh b/tools/get_cpu_count.sh index adb579a..a8b3972 100755 --- a/tools/get_cpu_count.sh +++ b/tools/get_cpu_count.sh @@ -1,18 +1,43 @@ #!/usr/bin/env bash set -e +set -u -which cc &>/dev/null || { echo "1" && exit 0; } +# Print number of enabled CPUs. Use this as a simple, platform-independent +# replacement for nproc or ncpus. +# +# The shell script wraps a simple C++ tool which will be compiled on demand. -prog="cpucount" -pushd "${0%/*}" >/dev/null 2>&1 +# This script's location. The proper way to do this in bash is using +# ${BASH_SOURCE[0]}; ignore the possibility of softlinks. +script_dir=$(cd $(dirname ${BASH_SOURCE[0]}) && pwd) +prog="$script_dir/cpucount" case "$(uname -s)" in *NT* | CYGWIN*) prog="${prog}.exe" ;; esac -[ ! -f $prog ] && cc cpucount.c -o cpucount &>/dev/null +if [ ! -f $prog ] +then + # Don't have cpucount. Build it. -./$prog + if ! which c++ >/dev/null + then + # Can't compile cpucount. Just give the safe answer. + echo 1 + exit 0 + fi + + # Attempt to compile cpucount.cpp. + if ! c++ $prog.cpp -o $prog &>/dev/null + then + # Okay, that didn't work... Try it with gcc/clang's option to force + # C++11. Versions of gcc older than 6.x still default to C++98. + c++ $prog.cpp -std=c++11 -o $prog >/dev/null + fi +fi + +# Now, at last: run cpucount. +$prog