(root)/
xz-5.4.5/
src/
common/
tuklib_cpucores.c
       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  
      46  extern uint32_t
      47  tuklib_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 = (uint32_t)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 = (uint32_t)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  	// On OpenBSD HW_NCPUONLINE tells the number of processor cores that
      76  	// are online so it is preferred over HW_NCPU which also counts cores
      77  	// that aren't currently available. The number of cores online is
      78  	// often less than HW_NCPU because OpenBSD disables simultaneous
      79  	// multi-threading (SMT) by default.
      80  #	ifdef HW_NCPUONLINE
      81  	int name[2] = { CTL_HW, HW_NCPUONLINE };
      82  #	else
      83  	int name[2] = { CTL_HW, HW_NCPU };
      84  #	endif
      85  	int cpus;
      86  	size_t cpus_size = sizeof(cpus);
      87  	if (sysctl(name, 2, &cpus, &cpus_size, NULL, 0) != -1
      88  			&& cpus_size == sizeof(cpus) && cpus > 0)
      89  		ret = (uint32_t)cpus;
      90  
      91  #elif defined(TUKLIB_CPUCORES_SYSCONF)
      92  #	ifdef _SC_NPROCESSORS_ONLN
      93  	// Most systems
      94  	const long cpus = sysconf(_SC_NPROCESSORS_ONLN);
      95  #	else
      96  	// IRIX
      97  	const long cpus = sysconf(_SC_NPROC_ONLN);
      98  #	endif
      99  	if (cpus > 0)
     100  		ret = (uint32_t)cpus;
     101  
     102  #elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
     103  	struct pst_dynamic pst;
     104  	if (pstat_getdynamic(&pst, sizeof(pst), 1, 0) != -1)
     105  		ret = (uint32_t)pst.psd_proc_cnt;
     106  #endif
     107  
     108  	return ret;
     109  }