xz: Add SIGTSTP handler for progress indicator time keeping.
[xz.git] / cmake / tuklib_cpucores.cmake
blobea16e427912b9df2fd95025c22c2a6a1045c8a1c
2 # tuklib_cpucores.cmake - see tuklib_cpucores.m4 for description and comments
4 # Author: Lasse Collin
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)
15     if(WIN32 OR CYGWIN)
16         # Nothing to do, the tuklib_cpucores.c handles it.
17         set(TUKLIB_CPUCORES_DEFINITIONS "" CACHE INTERNAL "")
18         return()
19     endif()
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.
25     #
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("
30             #include <sched.h>
31             int main(void)
32             {
33                 cpu_set_t cpu_mask;
34                 sched_getaffinity(0, sizeof(cpu_mask), &cpu_mask);
35                 return CPU_COUNT(&cpu_mask);
36             }
37         "
38         TUKLIB_CPUCORES_SCHED_GETAFFINITY)
39     if(TUKLIB_CPUCORES_SCHED_GETAFFINITY)
40         set(TUKLIB_CPUCORES_DEFINITIONS
41             "TUKLIB_CPUCORES_SCHED_GETAFFINITY"
42             CACHE INTERNAL "")
43         return()
44     endif()
46     # FreeBSD has both cpuset and sysctl. Look for cpuset first because
47     # it's a better approach.
48     #
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>
56             int main(void)
57             {
58                 cpuset_t set;
59                 cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
60                                    sizeof(set), &set);
61                 return 0;
62             }
63         "
64         TUKLIB_CPUCORES_CPUSET)
65     if(TUKLIB_CPUCORES_CPUSET)
66         set(TUKLIB_CPUCORES_DEFINITIONS "HAVE_PARAM_H;TUKLIB_CPUCORES_CPUSET"
67             CACHE INTERNAL "")
68         return()
69     endif()
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).
75     #
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)
79     if(HAVE_SYS_PARAM_H)
80         list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_PARAM_H)
81     endif()
82     check_c_source_compiles("
83             #ifdef __QNX__
84             compile error
85             #endif
86             #ifdef HAVE_SYS_PARAM_H
87             #   include <sys/param.h>
88             #endif
89             #include <sys/sysctl.h>
90             int main(void)
91             {
92             #ifdef HW_NCPUONLINE
93                 /* This is preferred on OpenBSD, see tuklib_cpucores.c. */
94                 int name[2] = { CTL_HW, HW_NCPUONLINE };
95             #else
96                 int name[2] = { CTL_HW, HW_NCPU };
97             #endif
98                 int cpus;
99                 size_t cpus_size = sizeof(cpus);
100                 sysctl(name, 2, &cpus, &cpus_size, NULL, 0);
101                 return 0;
102             }
103         "
104         TUKLIB_CPUCORES_SYSCTL)
105     if(TUKLIB_CPUCORES_SYSCTL)
106         if(HAVE_SYS_PARAM_H)
107             set(TUKLIB_CPUCORES_DEFINITIONS
108                 "HAVE_PARAM_H;TUKLIB_CPUCORES_SYSCTL"
109                 CACHE INTERNAL "")
110         else()
111             set(TUKLIB_CPUCORES_DEFINITIONS
112                 "TUKLIB_CPUCORES_SYSCTL"
113                 CACHE INTERNAL "")
114         endif()
115         return()
116     endif()
118     # Many platforms support sysconf().
119     check_c_source_compiles("
120             #include <unistd.h>
121             int main(void)
122             {
123                 long i;
124             #ifdef _SC_NPROCESSORS_ONLN
125                 /* Many systems using sysconf() */
126                 i = sysconf(_SC_NPROCESSORS_ONLN);
127             #else
128                 /* IRIX */
129                 i = sysconf(_SC_NPROC_ONLN);
130             #endif
131                 return 0;
132             }
133         "
134         TUKLIB_CPUCORES_SYSCONF)
135     if(TUKLIB_CPUCORES_SYSCONF)
136         set(TUKLIB_CPUCORES_DEFINITIONS "TUKLIB_CPUCORES_SYSCONF"
137             CACHE INTERNAL "")
138         return()
139     endif()
141     # HP-UX
142     check_c_source_compiles("
143             #include <sys/param.h>
144             #include <sys/pstat.h>
145             int main(void)
146             {
147                 struct pst_dynamic pst;
148                 pstat_getdynamic(&pst, sizeof(pst), 1, 0);
149                 (void)pst.psd_proc_cnt;
150                 return 0;
151             }
152         "
153         TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
154     if(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)
155         set(TUKLIB_CPUCORES_DEFINITIONS "TUKLIB_CPUCORES_PSTAT_GETDYNAMIC"
156             CACHE INTERNAL "")
157         return()
158     endif()
159 endfunction()
161 function(tuklib_cpucores TARGET_OR_ALL)
162     if(NOT DEFINED TUKLIB_CPUCORES_FOUND)
163         message(STATUS
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 "")
169         else()
170             set(TUKLIB_CPUCORES_FOUND 0 CACHE INTERNAL "")
171             message(WARNING
172                     "No method to detect the number of CPU cores was found")
173         endif()
174     endif()
176     if(TUKLIB_CPUCORES_FOUND)
177         tuklib_add_definitions("${TARGET_OR_ALL}"
178                                "${TUKLIB_CPUCORES_DEFINITIONS}")
179     endif()
180 endfunction()