15a645f22SBen Gras ///////////////////////////////////////////////////////////////////////////////
25a645f22SBen Gras //
35a645f22SBen Gras /// \file       tuklib_cpucores.c
45a645f22SBen Gras /// \brief      Get the number of CPU cores online
55a645f22SBen Gras //
65a645f22SBen Gras //  Author:     Lasse Collin
75a645f22SBen Gras //
85a645f22SBen Gras //  This file has been put into the public domain.
95a645f22SBen Gras //  You can do whatever you want with this file.
105a645f22SBen Gras //
115a645f22SBen Gras ///////////////////////////////////////////////////////////////////////////////
125a645f22SBen Gras 
135a645f22SBen Gras #include "tuklib_cpucores.h"
145a645f22SBen Gras 
15*0a6a1f1dSLionel Sambuc #if defined(_WIN32) || defined(__CYGWIN__)
16*0a6a1f1dSLionel Sambuc #	ifndef _WIN32_WINNT
17*0a6a1f1dSLionel Sambuc #		define _WIN32_WINNT 0x0500
18*0a6a1f1dSLionel Sambuc #	endif
19*0a6a1f1dSLionel Sambuc #	include <windows.h>
20*0a6a1f1dSLionel Sambuc 
21*0a6a1f1dSLionel Sambuc // FreeBSD
22*0a6a1f1dSLionel Sambuc #elif defined(TUKLIB_CPUCORES_CPUSET)
23*0a6a1f1dSLionel Sambuc #	include <sys/param.h>
24*0a6a1f1dSLionel Sambuc #	include <sys/cpuset.h>
25*0a6a1f1dSLionel Sambuc 
26*0a6a1f1dSLionel Sambuc #elif defined(TUKLIB_CPUCORES_SYSCTL)
275a645f22SBen Gras #	ifdef HAVE_SYS_PARAM_H
285a645f22SBen Gras #		include <sys/param.h>
295a645f22SBen Gras #	endif
305a645f22SBen Gras #	include <sys/sysctl.h>
315a645f22SBen Gras 
325a645f22SBen Gras #elif defined(TUKLIB_CPUCORES_SYSCONF)
335a645f22SBen Gras #	include <unistd.h>
345a645f22SBen Gras 
355a645f22SBen Gras // HP-UX
365a645f22SBen Gras #elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
375a645f22SBen Gras #	include <sys/param.h>
385a645f22SBen Gras #	include <sys/pstat.h>
395a645f22SBen Gras #endif
405a645f22SBen Gras 
415a645f22SBen Gras 
425a645f22SBen Gras extern uint32_t
tuklib_cpucores(void)435a645f22SBen Gras tuklib_cpucores(void)
445a645f22SBen Gras {
455a645f22SBen Gras 	uint32_t ret = 0;
465a645f22SBen Gras 
47*0a6a1f1dSLionel Sambuc #if defined(_WIN32) || defined(__CYGWIN__)
48*0a6a1f1dSLionel Sambuc 	SYSTEM_INFO sysinfo;
49*0a6a1f1dSLionel Sambuc 	GetSystemInfo(&sysinfo);
50*0a6a1f1dSLionel Sambuc 	ret = sysinfo.dwNumberOfProcessors;
51*0a6a1f1dSLionel Sambuc 
52*0a6a1f1dSLionel Sambuc #elif defined(TUKLIB_CPUCORES_CPUSET)
53*0a6a1f1dSLionel Sambuc 	cpuset_t set;
54*0a6a1f1dSLionel Sambuc 	if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
55*0a6a1f1dSLionel Sambuc 			sizeof(set), &set) == 0) {
56*0a6a1f1dSLionel Sambuc #	ifdef CPU_COUNT
57*0a6a1f1dSLionel Sambuc 		ret = CPU_COUNT(&set);
58*0a6a1f1dSLionel Sambuc #	else
59*0a6a1f1dSLionel Sambuc 		for (unsigned i = 0; i < CPU_SETSIZE; ++i)
60*0a6a1f1dSLionel Sambuc 			if (CPU_ISSET(i, &set))
61*0a6a1f1dSLionel Sambuc 				++ret;
62*0a6a1f1dSLionel Sambuc #	endif
63*0a6a1f1dSLionel Sambuc 	}
64*0a6a1f1dSLionel Sambuc 
65*0a6a1f1dSLionel Sambuc #elif defined(TUKLIB_CPUCORES_SYSCTL)
665a645f22SBen Gras 	int name[2] = { CTL_HW, HW_NCPU };
675a645f22SBen Gras 	int cpus;
685a645f22SBen Gras 	size_t cpus_size = sizeof(cpus);
695a645f22SBen Gras 	if (sysctl(name, 2, &cpus, &cpus_size, NULL, 0) != -1
705a645f22SBen Gras 			&& cpus_size == sizeof(cpus) && cpus > 0)
715a645f22SBen Gras 		ret = cpus;
725a645f22SBen Gras 
735a645f22SBen Gras #elif defined(TUKLIB_CPUCORES_SYSCONF)
745a645f22SBen Gras #	ifdef _SC_NPROCESSORS_ONLN
755a645f22SBen Gras 	// Most systems
765a645f22SBen Gras 	const long cpus = sysconf(_SC_NPROCESSORS_ONLN);
775a645f22SBen Gras #	else
785a645f22SBen Gras 	// IRIX
795a645f22SBen Gras 	const long cpus = sysconf(_SC_NPROC_ONLN);
805a645f22SBen Gras #	endif
815a645f22SBen Gras 	if (cpus > 0)
825a645f22SBen Gras 		ret = cpus;
835a645f22SBen Gras 
845a645f22SBen Gras #elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
855a645f22SBen Gras 	struct pst_dynamic pst;
865a645f22SBen Gras 	if (pstat_getdynamic(&pst, sizeof(pst), 1, 0) != -1)
875a645f22SBen Gras 		ret = pst.psd_proc_cnt;
885a645f22SBen Gras #endif
895a645f22SBen Gras 
905a645f22SBen Gras 	return ret;
915a645f22SBen Gras }
92