1 /////////////////////////////////////////////////////////////////////////////// 2 // 3 /// \file tuklib_cpucores.c 4 /// \brief Get the number of CPU cores online 5 // 6 // Author: Lasse Collin 7 // 8 // This file has been put into the public domain. 9 // You can do whatever you want with this file. 10 // 11 /////////////////////////////////////////////////////////////////////////////// 12 13 #include "tuklib_cpucores.h" 14 15 #if defined(_WIN32) || defined(__CYGWIN__) 16 # ifndef _WIN32_WINNT 17 # define _WIN32_WINNT 0x0500 18 # endif 19 # include <windows.h> 20 21 // glibc >= 2.9 22 #elif defined(TUKLIB_CPUCORES_SCHED_GETAFFINITY) 23 # include <sched.h> 24 25 // FreeBSD 26 #elif defined(TUKLIB_CPUCORES_CPUSET) 27 # include <sys/param.h> 28 # include <sys/cpuset.h> 29 30 #elif defined(TUKLIB_CPUCORES_SYSCTL) 31 # ifdef HAVE_SYS_PARAM_H 32 # include <sys/param.h> 33 # endif 34 # include <sys/sysctl.h> 35 36 #elif defined(TUKLIB_CPUCORES_SYSCONF) 37 # include <unistd.h> 38 39 // HP-UX 40 #elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC) 41 # include <sys/param.h> 42 # include <sys/pstat.h> 43 #endif 44 45 46 extern uint32_t 47 tuklib_cpucores(void) 48 { 49 uint32_t ret = 0; 50 51 #if defined(_WIN32) || defined(__CYGWIN__) 52 SYSTEM_INFO sysinfo; 53 GetSystemInfo(&sysinfo); 54 ret = sysinfo.dwNumberOfProcessors; 55 56 #elif defined(TUKLIB_CPUCORES_SCHED_GETAFFINITY) 57 cpu_set_t cpu_mask; 58 if (sched_getaffinity(0, sizeof(cpu_mask), &cpu_mask) == 0) 59 ret = (uint32_t)CPU_COUNT(&cpu_mask); 60 61 #elif defined(TUKLIB_CPUCORES_CPUSET) 62 cpuset_t set; 63 if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, 64 sizeof(set), &set) == 0) { 65 # ifdef CPU_COUNT 66 ret = (uint32_t)CPU_COUNT(&set); 67 # else 68 for (unsigned i = 0; i < CPU_SETSIZE; ++i) 69 if (CPU_ISSET(i, &set)) 70 ++ret; 71 # endif 72 } 73 74 #elif defined(TUKLIB_CPUCORES_SYSCTL) 75 // On OpenBSD HW_NCPUONLINE tells the number of processor cores that 76 // are online so it is preferred over HW_NCPU which also counts cores 77 // that aren't currently available. The number of cores online is 78 // often less than HW_NCPU because OpenBSD disables simultaneous 79 // multi-threading (SMT) by default. 80 # ifdef HW_NCPUONLINE 81 int name[2] = { CTL_HW, HW_NCPUONLINE }; 82 # else 83 int name[2] = { CTL_HW, HW_NCPU }; 84 # endif 85 int cpus; 86 size_t cpus_size = sizeof(cpus); 87 if (sysctl(name, 2, &cpus, &cpus_size, NULL, 0) != -1 88 && cpus_size == sizeof(cpus) && cpus > 0) 89 ret = (uint32_t)cpus; 90 91 #elif defined(TUKLIB_CPUCORES_SYSCONF) 92 # ifdef _SC_NPROCESSORS_ONLN 93 // Most systems 94 const long cpus = sysconf(_SC_NPROCESSORS_ONLN); 95 # else 96 // IRIX 97 const long cpus = sysconf(_SC_NPROC_ONLN); 98 # endif 99 if (cpus > 0) 100 ret = (uint32_t)cpus; 101 102 #elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC) 103 struct pst_dynamic pst; 104 if (pstat_getdynamic(&pst, sizeof(pst), 1, 0) != -1) 105 ret = (uint32_t)pst.psd_proc_cnt; 106 #endif 107 108 return ret; 109 } 110