1 /*
2 util.h - utility functions
3 Copyright (C) 2023, Yann Collet
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #if defined (__cplusplus)
21 extern "C" {
22 #endif
23
24
25 /*-****************************************
26 * Dependencies
27 ******************************************/
28 #include "util.h" /* note : ensure that platform.h is included first ! */
29
30 /*-****************************************
31 * count the number of cores
32 ******************************************/
33
34 #if defined(_WIN32)
35
36 #include <windows.h>
37
UTIL_countCores(void)38 int UTIL_countCores(void)
39 {
40 static int numCores = 0;
41 if (numCores != 0) return numCores;
42
43 { SYSTEM_INFO sysinfo;
44 GetSystemInfo(&sysinfo);
45 numCores = sysinfo.dwNumberOfProcessors;
46 }
47
48 if (numCores == 0) {
49 /* Unexpected result, fall back on 1 */
50 return numCores = 1;
51 }
52
53 return numCores;
54 }
55
56 #elif defined(__APPLE__)
57
58 #include <sys/sysctl.h>
59
60 /* Use apple-provided syscall
61 * see: man 3 sysctl */
62 int UTIL_countCores(void)
63 {
64 static S32 numCores = 0; /* apple specifies int32_t */
65 if (numCores != 0) return (int)numCores;
66
67 { size_t size = sizeof(S32);
68 int const ret = sysctlbyname("hw.logicalcpu", &numCores, &size, NULL, 0);
69 if (ret != 0) {
70 /* error: fall back on 1 */
71 numCores = 1;
72 }
73 }
74 return (int)numCores;
75 }
76
77 #elif defined(__linux__)
78
79 int UTIL_countCores(void)
80 {
81 static int numCores = 0;
82
83 if (numCores != 0) return numCores;
84
85 numCores = (int)sysconf(_SC_NPROCESSORS_ONLN);
86 if (numCores == -1) {
87 /* value not queryable, fall back on 1 */
88 return numCores = 1;
89 }
90
91 return numCores;
92 }
93
94 #elif defined(__FreeBSD__)
95
96 #include <stdio.h> /* perror */
97 #include <errno.h>
98 #include <sys/param.h>
99 #include <sys/sysctl.h>
100
101 /* Use physical core sysctl when available
102 * see: man 4 smp, man 3 sysctl */
103 int UTIL_countCores(void)
104 {
105 static int numCores = 0; /* freebsd sysctl is native int sized */
106 if (numCores != 0) return numCores;
107
108 #if __FreeBSD_version >= 1300008
109 { size_t size = sizeof(numCores);
110 int ret = sysctlbyname("kern.smp.cores", &numCores, &size, NULL, 0);
111 if (ret == 0) {
112 int perCore = 1;
113 ret = sysctlbyname("kern.smp.threads_per_core", &perCore, &size, NULL, 0);
114 /* default to physical cores if logical cannot be read */
115 if (ret != 0) /* error */
116 return numCores;
117 numCores *= perCore;
118 return numCores;
119 }
120 if (errno != ENOENT) {
121 perror("lz4: can't get number of cpus");
122 exit(1);
123 }
124 /* sysctl not present, fall through to older sysconf method */
125 }
126 #endif
127
128 numCores = (int)sysconf(_SC_NPROCESSORS_ONLN);
129 if (numCores == -1) {
130 /* value not queryable, fall back on 1 */
131 numCores = 1;
132 }
133 return numCores;
134 }
135
136 #elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__CYGWIN__)
137
138 /* Use POSIX sysconf
139 * see: man 3 sysconf */
140 int UTIL_countCores(void)
141 {
142 static int numCores = 0;
143 if (numCores != 0) return numCores;
144
145 numCores = (int)sysconf(_SC_NPROCESSORS_ONLN);
146 if (numCores == -1) {
147 /* value not queryable, fall back on 1 */
148 numCores = 1;
149 }
150 return numCores;
151 }
152
153 #else
154
155 int UTIL_countCores(void)
156 {
157 /* no clue */
158 return 1;
159 }
160
161 #endif
162
163 #if defined (__cplusplus)
164 }
165 #endif
166