1207753Smm///////////////////////////////////////////////////////////////////////////////
2207753Smm//
3207753Smm/// \file       tuklib_cpucores.c
4207753Smm/// \brief      Get the number of CPU cores online
5207753Smm//
6207753Smm//  Author:     Lasse Collin
7207753Smm//
8207753Smm//  This file has been put into the public domain.
9207753Smm//  You can do whatever you want with this file.
10207753Smm//
11207753Smm///////////////////////////////////////////////////////////////////////////////
12207753Smm
13207753Smm#include "tuklib_cpucores.h"
14207753Smm
15292588Sdelphij#if defined(_WIN32) || defined(__CYGWIN__)
16292588Sdelphij#	ifndef _WIN32_WINNT
17292588Sdelphij#		define _WIN32_WINNT 0x0500
18292588Sdelphij#	endif
19292588Sdelphij#	include <windows.h>
20292588Sdelphij
21312518Sdelphij// glibc >= 2.9
22312518Sdelphij#elif defined(TUKLIB_CPUCORES_SCHED_GETAFFINITY)
23312518Sdelphij#	include <sched.h>
24312518Sdelphij
25292588Sdelphij// FreeBSD
26292588Sdelphij#elif defined(TUKLIB_CPUCORES_CPUSET)
27292588Sdelphij#	include <sys/param.h>
28292588Sdelphij#	include <sys/cpuset.h>
29292588Sdelphij
30292588Sdelphij#elif defined(TUKLIB_CPUCORES_SYSCTL)
31207753Smm#	ifdef HAVE_SYS_PARAM_H
32207753Smm#		include <sys/param.h>
33207753Smm#	endif
34207753Smm#	include <sys/sysctl.h>
35207753Smm
36207753Smm#elif defined(TUKLIB_CPUCORES_SYSCONF)
37207753Smm#	include <unistd.h>
38213700Smm
39213700Smm// HP-UX
40213700Smm#elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
41213700Smm#	include <sys/param.h>
42213700Smm#	include <sys/pstat.h>
43207753Smm#endif
44207753Smm
45207753Smm
46207753Smmextern uint32_t
47207753Smmtuklib_cpucores(void)
48207753Smm{
49207753Smm	uint32_t ret = 0;
50207753Smm
51292588Sdelphij#if defined(_WIN32) || defined(__CYGWIN__)
52292588Sdelphij	SYSTEM_INFO sysinfo;
53292588Sdelphij	GetSystemInfo(&sysinfo);
54292588Sdelphij	ret = sysinfo.dwNumberOfProcessors;
55292588Sdelphij
56312518Sdelphij#elif defined(TUKLIB_CPUCORES_SCHED_GETAFFINITY)
57312518Sdelphij	cpu_set_t cpu_mask;
58312518Sdelphij	if (sched_getaffinity(0, sizeof(cpu_mask), &cpu_mask) == 0)
59312518Sdelphij		ret = CPU_COUNT(&cpu_mask);
60312518Sdelphij
61292588Sdelphij#elif defined(TUKLIB_CPUCORES_CPUSET)
62292588Sdelphij	cpuset_t set;
63292588Sdelphij	if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
64292588Sdelphij			sizeof(set), &set) == 0) {
65292588Sdelphij#	ifdef CPU_COUNT
66292588Sdelphij		ret = CPU_COUNT(&set);
67292588Sdelphij#	else
68292588Sdelphij		for (unsigned i = 0; i < CPU_SETSIZE; ++i)
69292588Sdelphij			if (CPU_ISSET(i, &set))
70292588Sdelphij				++ret;
71292588Sdelphij#	endif
72292588Sdelphij	}
73292588Sdelphij
74292588Sdelphij#elif defined(TUKLIB_CPUCORES_SYSCTL)
75207753Smm	int name[2] = { CTL_HW, HW_NCPU };
76207753Smm	int cpus;
77207753Smm	size_t cpus_size = sizeof(cpus);
78207753Smm	if (sysctl(name, 2, &cpus, &cpus_size, NULL, 0) != -1
79207753Smm			&& cpus_size == sizeof(cpus) && cpus > 0)
80213700Smm		ret = cpus;
81207753Smm
82207753Smm#elif defined(TUKLIB_CPUCORES_SYSCONF)
83207753Smm#	ifdef _SC_NPROCESSORS_ONLN
84207753Smm	// Most systems
85207753Smm	const long cpus = sysconf(_SC_NPROCESSORS_ONLN);
86207753Smm#	else
87207753Smm	// IRIX
88207753Smm	const long cpus = sysconf(_SC_NPROC_ONLN);
89207753Smm#	endif
90207753Smm	if (cpus > 0)
91213700Smm		ret = cpus;
92213700Smm
93213700Smm#elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
94213700Smm	struct pst_dynamic pst;
95213700Smm	if (pstat_getdynamic(&pst, sizeof(pst), 1, 0) != -1)
96213700Smm		ret = pst.psd_proc_cnt;
97207753Smm#endif
98207753Smm
99207753Smm	return ret;
100207753Smm}
101