xref: /aosp_15_r20/external/lz4/programs/util.c (revision 27162e4e17433d5aa7cb38e7b6a433a09405fc7f)
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