12940b44dSPeter Avalos ///////////////////////////////////////////////////////////////////////////////
22940b44dSPeter Avalos //
32940b44dSPeter Avalos /// \file       tuklib_cpucores.c
42940b44dSPeter Avalos /// \brief      Get the number of CPU cores online
52940b44dSPeter Avalos //
62940b44dSPeter Avalos //  Author:     Lasse Collin
72940b44dSPeter Avalos //
82940b44dSPeter Avalos //  This file has been put into the public domain.
92940b44dSPeter Avalos //  You can do whatever you want with this file.
102940b44dSPeter Avalos //
112940b44dSPeter Avalos ///////////////////////////////////////////////////////////////////////////////
122940b44dSPeter Avalos 
132940b44dSPeter Avalos #include "tuklib_cpucores.h"
142940b44dSPeter Avalos 
1515ab8c86SJohn Marino #if defined(_WIN32) || defined(__CYGWIN__)
1615ab8c86SJohn Marino #	ifndef _WIN32_WINNT
1715ab8c86SJohn Marino #		define _WIN32_WINNT 0x0500
1815ab8c86SJohn Marino #	endif
1915ab8c86SJohn Marino #	include <windows.h>
2015ab8c86SJohn Marino 
2146a2189dSzrj // glibc >= 2.9
2246a2189dSzrj #elif defined(TUKLIB_CPUCORES_SCHED_GETAFFINITY)
2346a2189dSzrj #	include <sched.h>
2446a2189dSzrj 
2515ab8c86SJohn Marino // FreeBSD
2615ab8c86SJohn Marino #elif defined(TUKLIB_CPUCORES_CPUSET)
2715ab8c86SJohn Marino #	include <sys/param.h>
2815ab8c86SJohn Marino #	include <sys/cpuset.h>
2915ab8c86SJohn Marino 
3015ab8c86SJohn Marino #elif defined(TUKLIB_CPUCORES_SYSCTL)
312940b44dSPeter Avalos #	ifdef HAVE_SYS_PARAM_H
322940b44dSPeter Avalos #		include <sys/param.h>
332940b44dSPeter Avalos #	endif
342940b44dSPeter Avalos #	include <sys/sysctl.h>
352940b44dSPeter Avalos 
362940b44dSPeter Avalos #elif defined(TUKLIB_CPUCORES_SYSCONF)
372940b44dSPeter Avalos #	include <unistd.h>
382940b44dSPeter Avalos 
392940b44dSPeter Avalos // HP-UX
402940b44dSPeter Avalos #elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
412940b44dSPeter Avalos #	include <sys/param.h>
422940b44dSPeter Avalos #	include <sys/pstat.h>
432940b44dSPeter Avalos #endif
442940b44dSPeter Avalos 
452940b44dSPeter Avalos 
462940b44dSPeter Avalos extern uint32_t
tuklib_cpucores(void)472940b44dSPeter Avalos tuklib_cpucores(void)
482940b44dSPeter Avalos {
492940b44dSPeter Avalos 	uint32_t ret = 0;
502940b44dSPeter Avalos 
5115ab8c86SJohn Marino #if defined(_WIN32) || defined(__CYGWIN__)
5215ab8c86SJohn Marino 	SYSTEM_INFO sysinfo;
5315ab8c86SJohn Marino 	GetSystemInfo(&sysinfo);
5415ab8c86SJohn Marino 	ret = sysinfo.dwNumberOfProcessors;
5515ab8c86SJohn Marino 
5646a2189dSzrj #elif defined(TUKLIB_CPUCORES_SCHED_GETAFFINITY)
5746a2189dSzrj 	cpu_set_t cpu_mask;
5846a2189dSzrj 	if (sched_getaffinity(0, sizeof(cpu_mask), &cpu_mask) == 0)
59*e151908bSDaniel Fojt 		ret = (uint32_t)CPU_COUNT(&cpu_mask);
6046a2189dSzrj 
6115ab8c86SJohn Marino #elif defined(TUKLIB_CPUCORES_CPUSET)
6215ab8c86SJohn Marino 	cpuset_t set;
6315ab8c86SJohn Marino 	if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
6415ab8c86SJohn Marino 			sizeof(set), &set) == 0) {
6515ab8c86SJohn Marino #	ifdef CPU_COUNT
66*e151908bSDaniel Fojt 		ret = (uint32_t)CPU_COUNT(&set);
6715ab8c86SJohn Marino #	else
6815ab8c86SJohn Marino 		for (unsigned i = 0; i < CPU_SETSIZE; ++i)
6915ab8c86SJohn Marino 			if (CPU_ISSET(i, &set))
7015ab8c86SJohn Marino 				++ret;
7115ab8c86SJohn Marino #	endif
7215ab8c86SJohn Marino 	}
7315ab8c86SJohn Marino 
7415ab8c86SJohn Marino #elif defined(TUKLIB_CPUCORES_SYSCTL)
752940b44dSPeter Avalos 	int name[2] = { CTL_HW, HW_NCPU };
762940b44dSPeter Avalos 	int cpus;
772940b44dSPeter Avalos 	size_t cpus_size = sizeof(cpus);
782940b44dSPeter Avalos 	if (sysctl(name, 2, &cpus, &cpus_size, NULL, 0) != -1
792940b44dSPeter Avalos 			&& cpus_size == sizeof(cpus) && cpus > 0)
80*e151908bSDaniel Fojt 		ret = (uint32_t)cpus;
812940b44dSPeter Avalos 
822940b44dSPeter Avalos #elif defined(TUKLIB_CPUCORES_SYSCONF)
832940b44dSPeter Avalos #	ifdef _SC_NPROCESSORS_ONLN
842940b44dSPeter Avalos 	// Most systems
852940b44dSPeter Avalos 	const long cpus = sysconf(_SC_NPROCESSORS_ONLN);
862940b44dSPeter Avalos #	else
872940b44dSPeter Avalos 	// IRIX
882940b44dSPeter Avalos 	const long cpus = sysconf(_SC_NPROC_ONLN);
892940b44dSPeter Avalos #	endif
902940b44dSPeter Avalos 	if (cpus > 0)
91*e151908bSDaniel Fojt 		ret = (uint32_t)cpus;
922940b44dSPeter Avalos 
932940b44dSPeter Avalos #elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
942940b44dSPeter Avalos 	struct pst_dynamic pst;
952940b44dSPeter Avalos 	if (pstat_getdynamic(&pst, sizeof(pst), 1, 0) != -1)
96*e151908bSDaniel Fojt 		ret = (uint32_t)pst.psd_proc_cnt;
972940b44dSPeter Avalos #endif
982940b44dSPeter Avalos 
992940b44dSPeter Avalos 	return ret;
1002940b44dSPeter Avalos }
101