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
46extern uint32_t
47tuklib_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 = 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 = 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	int name[2] = { CTL_HW, HW_NCPU };
76	int cpus;
77	size_t cpus_size = sizeof(cpus);
78	if (sysctl(name, 2, &cpus, &cpus_size, NULL, 0) != -1
79			&& cpus_size == sizeof(cpus) && cpus > 0)
80		ret = cpus;
81
82#elif defined(TUKLIB_CPUCORES_SYSCONF)
83#	ifdef _SC_NPROCESSORS_ONLN
84	// Most systems
85	const long cpus = sysconf(_SC_NPROCESSORS_ONLN);
86#	else
87	// IRIX
88	const long cpus = sysconf(_SC_NPROC_ONLN);
89#	endif
90	if (cpus > 0)
91		ret = cpus;
92
93#elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
94	struct pst_dynamic pst;
95	if (pstat_getdynamic(&pst, sizeof(pst), 1, 0) != -1)
96		ret = pst.psd_proc_cnt;
97#endif
98
99	return ret;
100}
101