2 # tuklib_cpucores.cmake - see tuklib_cpucores.m4 for description and comments
6 # This file has been put into the public domain.
7 # You can do whatever you want with this file.
10 include("${CMAKE_CURRENT_LIST_DIR}/tuklib_common.cmake")
11 include(CheckCSourceCompiles)
12 include(CheckIncludeFile)
14 function(tuklib_cpucores_internal_check)
16 # Nothing to do, the tuklib_cpucores.c handles it.
17 set(TUKLIB_CPUCORES_DEFINITIONS "" CACHE INTERNAL "")
21 # glibc-based systems (GNU/Linux and GNU/kFreeBSD) have
22 # sched_getaffinity(). The CPU_COUNT() macro was added in glibc 2.9.
23 # glibc 2.9 is old enough that if someone uses the code on older glibc,
24 # the fallback to sysconf() should be good enough.
26 # NOTE: This required that _GNU_SOURCE is defined. We assume that whatever
27 # feature test macros the caller wants to use are already set in
28 # CMAKE_REQUIRED_DEFINES and in the target defines.
29 check_c_source_compiles("
34 sched_getaffinity(0, sizeof(cpu_mask), &cpu_mask);
35 return CPU_COUNT(&cpu_mask);
38 TUKLIB_CPUCORES_SCHED_GETAFFINITY)
39 if(TUKLIB_CPUCORES_SCHED_GETAFFINITY)
40 set(TUKLIB_CPUCORES_DEFINITIONS
41 "TUKLIB_CPUCORES_SCHED_GETAFFINITY"
46 # FreeBSD has both cpuset and sysctl. Look for cpuset first because
47 # it's a better approach.
49 # This test would match on GNU/kFreeBSD too but it would require
50 # -lfreebsd-glue when linking and thus in the current form this would
51 # fail on GNU/kFreeBSD. The above test for sched_getaffinity() matches
52 # on GNU/kFreeBSD so the test below should never run on that OS.
53 check_c_source_compiles("
54 #include <sys/param.h>
55 #include <sys/cpuset.h>
59 cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
64 TUKLIB_CPUCORES_CPUSET)
65 if(TUKLIB_CPUCORES_CPUSET)
66 set(TUKLIB_CPUCORES_DEFINITIONS "HAVE_PARAM_H;TUKLIB_CPUCORES_CPUSET"
71 # On OS/2, both sysconf() and sysctl() pass the tests in this file,
72 # but only sysctl() works. On QNX it's the opposite: only sysconf() works
73 # (although it assumes that _POSIX_SOURCE, _XOPEN_SOURCE, and
74 # _POSIX_C_SOURCE are undefined or alternatively _QNX_SOURCE is defined).
76 # We test sysctl() first and intentionally break the sysctl() test on QNX
77 # so that sysctl() is never used on QNX.
78 check_include_file(sys/param.h HAVE_SYS_PARAM_H)
80 list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_PARAM_H)
82 check_c_source_compiles("
86 #ifdef HAVE_SYS_PARAM_H
87 # include <sys/param.h>
89 #include <sys/sysctl.h>
93 /* This is preferred on OpenBSD, see tuklib_cpucores.c. */
94 int name[2] = { CTL_HW, HW_NCPUONLINE };
96 int name[2] = { CTL_HW, HW_NCPU };
99 size_t cpus_size = sizeof(cpus);
100 sysctl(name, 2, &cpus, &cpus_size, NULL, 0);
104 TUKLIB_CPUCORES_SYSCTL)
105 if(TUKLIB_CPUCORES_SYSCTL)
107 set(TUKLIB_CPUCORES_DEFINITIONS
108 "HAVE_PARAM_H;TUKLIB_CPUCORES_SYSCTL"
111 set(TUKLIB_CPUCORES_DEFINITIONS
112 "TUKLIB_CPUCORES_SYSCTL"
118 # Many platforms support sysconf().
119 check_c_source_compiles("
124 #ifdef _SC_NPROCESSORS_ONLN
125 /* Many systems using sysconf() */
126 i = sysconf(_SC_NPROCESSORS_ONLN);
129 i = sysconf(_SC_NPROC_ONLN);
134 TUKLIB_CPUCORES_SYSCONF)
135 if(TUKLIB_CPUCORES_SYSCONF)
136 set(TUKLIB_CPUCORES_DEFINITIONS "TUKLIB_CPUCORES_SYSCONF"
142 check_c_source_compiles("
143 #include <sys/param.h>
144 #include <sys/pstat.h>
147 struct pst_dynamic pst;
148 pstat_getdynamic(&pst, sizeof(pst), 1, 0);
149 (void)pst.psd_proc_cnt;
153 TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
154 if(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
155 set(TUKLIB_CPUCORES_DEFINITIONS "TUKLIB_CPUCORES_PSTAT_GETDYNAMIC"
161 function(tuklib_cpucores TARGET_OR_ALL)
162 if(NOT DEFINED TUKLIB_CPUCORES_FOUND)
164 "Checking how to detect the number of available CPU cores")
165 tuklib_cpucores_internal_check()
167 if(DEFINED TUKLIB_CPUCORES_DEFINITIONS)
168 set(TUKLIB_CPUCORES_FOUND 1 CACHE INTERNAL "")
170 set(TUKLIB_CPUCORES_FOUND 0 CACHE INTERNAL "")
172 "No method to detect the number of CPU cores was found")
176 if(TUKLIB_CPUCORES_FOUND)
177 tuklib_add_definitions("${TARGET_OR_ALL}"
178 "${TUKLIB_CPUCORES_DEFINITIONS}")