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 // FreeBSD
22 #elif defined(TUKLIB_CPUCORES_CPUSET)
23 #	include <sys/param.h>
24 #	include <sys/cpuset.h>
25 
26 #elif defined(TUKLIB_CPUCORES_SYSCTL)
27 #	ifdef HAVE_SYS_PARAM_H
28 #		include <sys/param.h>
29 #	endif
30 #	include <sys/sysctl.h>
31 
32 #elif defined(TUKLIB_CPUCORES_SYSCONF)
33 #	include <unistd.h>
34 
35 // HP-UX
36 #elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
37 #	include <sys/param.h>
38 #	include <sys/pstat.h>
39 #endif
40 
41 
42 extern uint32_t
43 tuklib_cpucores(void)
44 {
45 	uint32_t ret = 0;
46 
47 #if defined(_WIN32) || defined(__CYGWIN__)
48 	SYSTEM_INFO sysinfo;
49 	GetSystemInfo(&sysinfo);
50 	ret = sysinfo.dwNumberOfProcessors;
51 
52 #elif defined(TUKLIB_CPUCORES_CPUSET)
53 	cpuset_t set;
54 	if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
55 			sizeof(set), &set) == 0) {
56 #	ifdef CPU_COUNT
57 		ret = CPU_COUNT(&set);
58 #	else
59 		for (unsigned i = 0; i < CPU_SETSIZE; ++i)
60 			if (CPU_ISSET(i, &set))
61 				++ret;
62 #	endif
63 	}
64 
65 #elif defined(TUKLIB_CPUCORES_SYSCTL)
66 	int name[2] = { CTL_HW, HW_NCPU };
67 	int cpus;
68 	size_t cpus_size = sizeof(cpus);
69 	if (sysctl(name, 2, &cpus, &cpus_size, NULL, 0) != -1
70 			&& cpus_size == sizeof(cpus) && cpus > 0)
71 		ret = cpus;
72 
73 #elif defined(TUKLIB_CPUCORES_SYSCONF)
74 #	ifdef _SC_NPROCESSORS_ONLN
75 	// Most systems
76 	const long cpus = sysconf(_SC_NPROCESSORS_ONLN);
77 #	else
78 	// IRIX
79 	const long cpus = sysconf(_SC_NPROC_ONLN);
80 #	endif
81 	if (cpus > 0)
82 		ret = cpus;
83 
84 #elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
85 	struct pst_dynamic pst;
86 	if (pstat_getdynamic(&pst, sizeof(pst), 1, 0) != -1)
87 		ret = pst.psd_proc_cnt;
88 #endif
89 
90 	return ret;
91 }
92