/src/hwloc/include/private/misc.h
Line | Count | Source |
1 | | /* |
2 | | * SPDX-License-Identifier: BSD-3-Clause |
3 | | * Copyright © 2009 CNRS |
4 | | * Copyright © 2009-2025 Inria. All rights reserved. |
5 | | * Copyright © 2009-2012 Université Bordeaux |
6 | | * Copyright © 2011 Cisco Systems, Inc. All rights reserved. |
7 | | * See COPYING in top-level directory. |
8 | | */ |
9 | | |
10 | | /* Misc macros and inlines. */ |
11 | | |
12 | | #ifndef HWLOC_PRIVATE_MISC_H |
13 | | #define HWLOC_PRIVATE_MISC_H |
14 | | |
15 | | #include "hwloc/autogen/config.h" |
16 | | #include "private/autogen/config.h" |
17 | | #include "hwloc.h" |
18 | | |
19 | | #ifdef HAVE_UNISTD_H |
20 | | #include <unistd.h> /* for sysconf() and getpagesize(), but not enough to avoid a missing prototype warning on MinGW? */ |
21 | | #endif |
22 | | #ifdef HWLOC_HAVE_DECL_STRNCASECMP |
23 | | #ifdef HAVE_STRINGS_H |
24 | | #include <strings.h> |
25 | | #endif |
26 | | #else |
27 | | #ifdef HAVE_CTYPE_H |
28 | | #include <ctype.h> |
29 | | #endif |
30 | | #endif |
31 | | |
32 | | #define HWLOC_BITS_PER_LONG (HWLOC_SIZEOF_UNSIGNED_LONG * 8) |
33 | | #define HWLOC_BITS_PER_INT (HWLOC_SIZEOF_UNSIGNED_INT * 8) |
34 | | |
35 | | #if (HWLOC_BITS_PER_LONG != 32) && (HWLOC_BITS_PER_LONG != 64) |
36 | | #error "unknown size for unsigned long." |
37 | | #endif |
38 | | |
39 | | #if (HWLOC_BITS_PER_INT != 16) && (HWLOC_BITS_PER_INT != 32) && (HWLOC_BITS_PER_INT != 64) |
40 | | #error "unknown size for unsigned int." |
41 | | #endif |
42 | | |
43 | | /* internal-use-only value for when we don't know the type or don't have any value */ |
44 | | #define HWLOC_OBJ_TYPE_NONE ((hwloc_obj_type_t) -1) |
45 | | |
46 | | /** |
47 | | * ffsl helpers. |
48 | | */ |
49 | | |
50 | | #if defined(HWLOC_HAVE_BROKEN_FFS) |
51 | | |
52 | | /* System has a broken ffs(). |
53 | | * We must check the before __GNUC__ or HWLOC_HAVE_FFSL |
54 | | */ |
55 | | # define HWLOC_NO_FFS |
56 | | |
57 | | #elif defined(__GNUC__) |
58 | | |
59 | | # if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4)) |
60 | | /* Starting from 3.4, gcc has a long variant. */ |
61 | | # define hwloc_ffsl(x) __builtin_ffsl(x) |
62 | | # else |
63 | | # define hwloc_ffs(x) __builtin_ffs(x) |
64 | | # define HWLOC_NEED_FFSL |
65 | | # endif |
66 | | |
67 | | #elif defined(HWLOC_HAVE_FFSL) |
68 | | |
69 | | # ifndef HWLOC_HAVE_DECL_FFSL |
70 | | extern int ffsl(long) __hwloc_attribute_const; |
71 | | # endif |
72 | | |
73 | | # define hwloc_ffsl(x) ffsl(x) |
74 | | |
75 | | #elif defined(HWLOC_HAVE_FFS) |
76 | | |
77 | | # ifndef HWLOC_HAVE_DECL_FFS |
78 | | extern int ffs(int) __hwloc_attribute_const; |
79 | | # endif |
80 | | |
81 | | # define hwloc_ffs(x) ffs(x) |
82 | | # define HWLOC_NEED_FFSL |
83 | | |
84 | | #else /* no ffs implementation */ |
85 | | |
86 | | # define HWLOC_NO_FFS |
87 | | |
88 | | #endif |
89 | | |
90 | | #ifdef HWLOC_NO_FFS |
91 | | |
92 | | /* no ffs or it is known to be broken */ |
93 | | static __hwloc_inline int |
94 | | hwloc_ffsl_manual(unsigned long x) __hwloc_attribute_const; |
95 | | static __hwloc_inline int |
96 | | hwloc_ffsl_manual(unsigned long x) |
97 | | { |
98 | | int i; |
99 | | |
100 | | if (!x) |
101 | | return 0; |
102 | | |
103 | | i = 1; |
104 | | #if HWLOC_BITS_PER_LONG >= 64 |
105 | | if (!(x & 0xfffffffful)) { |
106 | | x >>= 32; |
107 | | i += 32; |
108 | | } |
109 | | #endif |
110 | | if (!(x & 0xffffu)) { |
111 | | x >>= 16; |
112 | | i += 16; |
113 | | } |
114 | | if (!(x & 0xff)) { |
115 | | x >>= 8; |
116 | | i += 8; |
117 | | } |
118 | | if (!(x & 0xf)) { |
119 | | x >>= 4; |
120 | | i += 4; |
121 | | } |
122 | | if (!(x & 0x3)) { |
123 | | x >>= 2; |
124 | | i += 2; |
125 | | } |
126 | | if (!(x & 0x1)) { |
127 | | x >>= 1; |
128 | | i += 1; |
129 | | } |
130 | | |
131 | | return i; |
132 | | } |
133 | | /* always define hwloc_ffsl as a macro, to avoid renaming breakage */ |
134 | | #define hwloc_ffsl hwloc_ffsl_manual |
135 | | |
136 | | #elif defined(HWLOC_NEED_FFSL) |
137 | | |
138 | | /* We only have an int ffs(int) implementation, build a long one. */ |
139 | | |
140 | | /* First make it 32 bits if it was only 16. */ |
141 | | static __hwloc_inline int |
142 | | hwloc_ffs32(unsigned long x) __hwloc_attribute_const; |
143 | | static __hwloc_inline int |
144 | | hwloc_ffs32(unsigned long x) |
145 | | { |
146 | | #if HWLOC_BITS_PER_INT == 16 |
147 | | int low_ffs, hi_ffs; |
148 | | |
149 | | low_ffs = hwloc_ffs(x & 0xfffful); |
150 | | if (low_ffs) |
151 | | return low_ffs; |
152 | | |
153 | | hi_ffs = hwloc_ffs(x >> 16); |
154 | | if (hi_ffs) |
155 | | return hi_ffs + 16; |
156 | | |
157 | | return 0; |
158 | | #else |
159 | | return hwloc_ffs(x); |
160 | | #endif |
161 | | } |
162 | | |
163 | | /* Then make it 64 bit if longs are. */ |
164 | | static __hwloc_inline int |
165 | | hwloc_ffsl_from_ffs32(unsigned long x) __hwloc_attribute_const; |
166 | | static __hwloc_inline int |
167 | | hwloc_ffsl_from_ffs32(unsigned long x) |
168 | | { |
169 | | #if HWLOC_BITS_PER_LONG == 64 |
170 | | int low_ffs, hi_ffs; |
171 | | |
172 | | low_ffs = hwloc_ffs32(x & 0xfffffffful); |
173 | | if (low_ffs) |
174 | | return low_ffs; |
175 | | |
176 | | hi_ffs = hwloc_ffs32(x >> 32); |
177 | | if (hi_ffs) |
178 | | return hi_ffs + 32; |
179 | | |
180 | | return 0; |
181 | | #else |
182 | | return hwloc_ffs32(x); |
183 | | #endif |
184 | | } |
185 | | /* always define hwloc_ffsl as a macro, to avoid renaming breakage */ |
186 | | #define hwloc_ffsl hwloc_ffsl_from_ffs32 |
187 | | |
188 | | #endif |
189 | | |
190 | | /** |
191 | | * flsl helpers. |
192 | | */ |
193 | | #ifdef __GNUC__ |
194 | | |
195 | | # if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4)) |
196 | | # define hwloc_flsl(x) ((x) ? (8*sizeof(long) - __builtin_clzl(x)) : 0) |
197 | | # else |
198 | | # define hwloc_fls(x) ((x) ? (8*sizeof(int) - __builtin_clz(x)) : 0) |
199 | | # define HWLOC_NEED_FLSL |
200 | | # endif |
201 | | |
202 | | #elif defined(HWLOC_HAVE_FLSL) |
203 | | |
204 | | # ifndef HWLOC_HAVE_DECL_FLSL |
205 | | extern int flsl(long) __hwloc_attribute_const; |
206 | | # endif |
207 | | |
208 | | # define hwloc_flsl(x) flsl(x) |
209 | | |
210 | | #elif defined(HWLOC_HAVE_CLZL) |
211 | | |
212 | | # ifndef HWLOC_HAVE_DECL_CLZL |
213 | | extern int clzl(long) __hwloc_attribute_const; |
214 | | # endif |
215 | | |
216 | | # define hwloc_flsl(x) ((x) ? (8*sizeof(long) - clzl(x)) : 0) |
217 | | |
218 | | #elif defined(HWLOC_HAVE_FLS) |
219 | | |
220 | | # ifndef HWLOC_HAVE_DECL_FLS |
221 | | extern int fls(int) __hwloc_attribute_const; |
222 | | # endif |
223 | | |
224 | | # define hwloc_fls(x) fls(x) |
225 | | # define HWLOC_NEED_FLSL |
226 | | |
227 | | #elif defined(HWLOC_HAVE_CLZ) |
228 | | |
229 | | # ifndef HWLOC_HAVE_DECL_CLZ |
230 | | extern int clz(int) __hwloc_attribute_const; |
231 | | # endif |
232 | | |
233 | | # define hwloc_fls(x) ((x) ? (8*sizeof(int) - clz(x)) : 0) |
234 | | # define HWLOC_NEED_FLSL |
235 | | |
236 | | #else /* no fls implementation */ |
237 | | |
238 | | static __hwloc_inline int |
239 | | hwloc_flsl_manual(unsigned long x) __hwloc_attribute_const; |
240 | | static __hwloc_inline int |
241 | | hwloc_flsl_manual(unsigned long x) |
242 | | { |
243 | | int i = 0; |
244 | | |
245 | | if (!x) |
246 | | return 0; |
247 | | |
248 | | i = 1; |
249 | | #if HWLOC_BITS_PER_LONG >= 64 |
250 | | if ((x & 0xffffffff00000000ul)) { |
251 | | x >>= 32; |
252 | | i += 32; |
253 | | } |
254 | | #endif |
255 | | if ((x & 0xffff0000u)) { |
256 | | x >>= 16; |
257 | | i += 16; |
258 | | } |
259 | | if ((x & 0xff00)) { |
260 | | x >>= 8; |
261 | | i += 8; |
262 | | } |
263 | | if ((x & 0xf0)) { |
264 | | x >>= 4; |
265 | | i += 4; |
266 | | } |
267 | | if ((x & 0xc)) { |
268 | | x >>= 2; |
269 | | i += 2; |
270 | | } |
271 | | if ((x & 0x2)) { |
272 | | x >>= 1; |
273 | | i += 1; |
274 | | } |
275 | | |
276 | | return i; |
277 | | } |
278 | | /* always define hwloc_flsl as a macro, to avoid renaming breakage */ |
279 | | #define hwloc_flsl hwloc_flsl_manual |
280 | | |
281 | | #endif |
282 | | |
283 | | #ifdef HWLOC_NEED_FLSL |
284 | | |
285 | | /* We only have an int fls(int) implementation, build a long one. */ |
286 | | |
287 | | /* First make it 32 bits if it was only 16. */ |
288 | | static __hwloc_inline int |
289 | | hwloc_fls32(unsigned long x) __hwloc_attribute_const; |
290 | | static __hwloc_inline int |
291 | | hwloc_fls32(unsigned long x) |
292 | | { |
293 | | #if HWLOC_BITS_PER_INT == 16 |
294 | | int low_fls, hi_fls; |
295 | | |
296 | | hi_fls = hwloc_fls(x >> 16); |
297 | | if (hi_fls) |
298 | | return hi_fls + 16; |
299 | | |
300 | | low_fls = hwloc_fls(x & 0xfffful); |
301 | | if (low_fls) |
302 | | return low_fls; |
303 | | |
304 | | return 0; |
305 | | #else |
306 | | return hwloc_fls(x); |
307 | | #endif |
308 | | } |
309 | | |
310 | | /* Then make it 64 bit if longs are. */ |
311 | | static __hwloc_inline int |
312 | | hwloc_flsl_from_fls32(unsigned long x) __hwloc_attribute_const; |
313 | | static __hwloc_inline int |
314 | | hwloc_flsl_from_fls32(unsigned long x) |
315 | | { |
316 | | #if HWLOC_BITS_PER_LONG == 64 |
317 | | int low_fls, hi_fls; |
318 | | |
319 | | hi_fls = hwloc_fls32(x >> 32); |
320 | | if (hi_fls) |
321 | | return hi_fls + 32; |
322 | | |
323 | | low_fls = hwloc_fls32(x & 0xfffffffful); |
324 | | if (low_fls) |
325 | | return low_fls; |
326 | | |
327 | | return 0; |
328 | | #else |
329 | | return hwloc_fls32(x); |
330 | | #endif |
331 | | } |
332 | | /* always define hwloc_flsl as a macro, to avoid renaming breakage */ |
333 | | #define hwloc_flsl hwloc_flsl_from_fls32 |
334 | | |
335 | | #endif |
336 | | |
337 | | static __hwloc_inline int |
338 | | hwloc_weight_long(unsigned long w) __hwloc_attribute_const; |
339 | | static __hwloc_inline int |
340 | | hwloc_weight_long(unsigned long w) |
341 | 0 | { |
342 | 0 | #if HWLOC_BITS_PER_LONG == 32 |
343 | 0 | #if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__) >= 4) |
344 | 0 | return __builtin_popcount(w); |
345 | 0 | #else |
346 | 0 | unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555); |
347 | 0 | res = (res & 0x33333333) + ((res >> 2) & 0x33333333); |
348 | 0 | res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F); |
349 | 0 | res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF); |
350 | 0 | return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF); |
351 | 0 | #endif |
352 | 0 | #else /* HWLOC_BITS_PER_LONG == 32 */ |
353 | 0 | #if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__) >= 4) |
354 | 0 | return __builtin_popcountll(w); |
355 | 0 | #else |
356 | 0 | unsigned long res; |
357 | 0 | res = (w & 0x5555555555555555ul) + ((w >> 1) & 0x5555555555555555ul); |
358 | 0 | res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul); |
359 | 0 | res = (res & 0x0F0F0F0F0F0F0F0Ful) + ((res >> 4) & 0x0F0F0F0F0F0F0F0Ful); |
360 | 0 | res = (res & 0x00FF00FF00FF00FFul) + ((res >> 8) & 0x00FF00FF00FF00FFul); |
361 | 0 | res = (res & 0x0000FFFF0000FFFFul) + ((res >> 16) & 0x0000FFFF0000FFFFul); |
362 | 0 | return (res & 0x00000000FFFFFFFFul) + ((res >> 32) & 0x00000000FFFFFFFFul); |
363 | 0 | #endif |
364 | 0 | #endif /* HWLOC_BITS_PER_LONG == 64 */ |
365 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc_weight_long Unexecuted instantiation: base64.c:hwloc_weight_long |
366 | | |
367 | | #if !HAVE_DECL_STRTOULL && defined(HAVE_STRTOULL) |
368 | | unsigned long long int strtoull(const char *nptr, char **endptr, int base); |
369 | | #endif |
370 | | |
371 | | static __hwloc_inline int hwloc_strncasecmp(const char *s1, const char *s2, size_t n) |
372 | 0 | { |
373 | 0 | #ifdef HWLOC_HAVE_DECL_STRNCASECMP |
374 | 0 | return strncasecmp(s1, s2, n); |
375 | 0 | #else |
376 | 0 | while (n) { |
377 | 0 | char c1 = tolower((unsigned char)*s1), c2 = tolower((unsigned char)*s2); |
378 | 0 | if (!c1 || !c2 || c1 != c2) |
379 | 0 | return c1-c2; |
380 | 0 | n--; s1++; s2++; |
381 | 0 | } |
382 | 0 | return 0; |
383 | 0 | #endif |
384 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc_strncasecmp Unexecuted instantiation: base64.c:hwloc_strncasecmp |
385 | | |
386 | | static __hwloc_inline hwloc_obj_type_t hwloc_cache_type_by_depth_type(unsigned depth, hwloc_obj_cache_type_t type) |
387 | 0 | { |
388 | 0 | if (type == HWLOC_OBJ_CACHE_INSTRUCTION) { |
389 | 0 | if (depth >= 1 && depth <= 3) |
390 | 0 | return HWLOC_OBJ_L1ICACHE + depth-1; |
391 | 0 | else |
392 | 0 | return HWLOC_OBJ_TYPE_NONE; |
393 | 0 | } else { |
394 | 0 | if (depth >= 1 && depth <= 5) |
395 | 0 | return HWLOC_OBJ_L1CACHE + depth-1; |
396 | 0 | else |
397 | 0 | return HWLOC_OBJ_TYPE_NONE; |
398 | 0 | } |
399 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc_cache_type_by_depth_type Unexecuted instantiation: base64.c:hwloc_cache_type_by_depth_type |
400 | | |
401 | | #define HWLOC_BITMAP_EQUAL 0 /* Bitmaps are equal */ |
402 | | #define HWLOC_BITMAP_INCLUDED 1 /* First bitmap included in second */ |
403 | | #define HWLOC_BITMAP_CONTAINS 2 /* First bitmap contains second */ |
404 | | #define HWLOC_BITMAP_INTERSECTS 3 /* Bitmaps intersect without any inclusion */ |
405 | | #define HWLOC_BITMAP_DIFFERENT 4 /* Bitmaps do not intersect */ |
406 | | |
407 | | /* Compare bitmaps \p bitmap1 and \p bitmap2 from an inclusion point of view. */ |
408 | | HWLOC_DECLSPEC int hwloc_bitmap_compare_inclusion(hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2) __hwloc_attribute_pure; |
409 | | |
410 | | /* Return a stringified PCI class. */ |
411 | | HWLOC_DECLSPEC extern const char * hwloc_pci_class_string(unsigned short class_id); |
412 | | |
413 | | /* Parse a PCI link speed (GT/s) string from Linux sysfs */ |
414 | | #ifdef HWLOC_LINUX_SYS |
415 | | #include <stdlib.h> /* for atof() */ |
416 | | static __hwloc_inline float |
417 | | hwloc_linux_pci_link_speed_from_string(const char *string) |
418 | 0 | { |
419 | 0 | /* don't parse Gen1 with atof() since it expects a localized string |
420 | 0 | * while the kernel sysfs files aren't. |
421 | 0 | */ |
422 | 0 | if (!strncmp(string, "2.5 ", 4)) |
423 | 0 | /* "2.5 GT/s" is Gen1 with 8/10 encoding */ |
424 | 0 | return 2.5 * .8; |
425 | 0 |
|
426 | 0 | /* also hardwire Gen2 since it also has a specific encoding */ |
427 | 0 | if (!strncmp(string, "5 ", 2)) |
428 | 0 | /* "5 GT/s" is Gen2 with 8/10 encoding */ |
429 | 0 | return 5 * .8; |
430 | 0 |
|
431 | 0 | /* handle Gen3+ in a generic way */ |
432 | 0 | return atof(string) * 128./130; /* Gen3+ encoding is 128/130 */ |
433 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc_linux_pci_link_speed_from_string Unexecuted instantiation: base64.c:hwloc_linux_pci_link_speed_from_string |
434 | | #endif |
435 | | |
436 | | /* Traverse children of a parent */ |
437 | | #define for_each_child(child, parent) for(child = parent->first_child; child; child = child->next_sibling) |
438 | | #define for_each_memory_child(child, parent) for(child = parent->memory_first_child; child; child = child->next_sibling) |
439 | | #define for_each_io_child(child, parent) for(child = parent->io_first_child; child; child = child->next_sibling) |
440 | | #define for_each_misc_child(child, parent) for(child = parent->misc_first_child; child; child = child->next_sibling) |
441 | | |
442 | | /* Any object attached to normal children */ |
443 | | static __hwloc_inline int hwloc__obj_type_is_normal (hwloc_obj_type_t type) |
444 | 0 | { |
445 | 0 | /* type contiguity is asserted in topology_check() */ |
446 | 0 | return type <= HWLOC_OBJ_GROUP; |
447 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc__obj_type_is_normal Unexecuted instantiation: base64.c:hwloc__obj_type_is_normal |
448 | | |
449 | | /* Any object attached to memory children, currently NUMA nodes or Memory-side caches */ |
450 | | static __hwloc_inline int hwloc__obj_type_is_memory (hwloc_obj_type_t type) |
451 | 0 | { |
452 | 0 | /* type contiguity is asserted in topology_check() */ |
453 | 0 | return type >= HWLOC_OBJ_NUMANODE && type <= HWLOC_OBJ_MEMCACHE; |
454 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc__obj_type_is_memory Unexecuted instantiation: base64.c:hwloc__obj_type_is_memory |
455 | | |
456 | | /* I/O or Misc object, without cpusets or nodesets. */ |
457 | | static __hwloc_inline int hwloc__obj_type_is_special (hwloc_obj_type_t type) |
458 | 0 | { |
459 | 0 | /* type contiguity is asserted in topology_check() */ |
460 | 0 | return type >= HWLOC_OBJ_BRIDGE && type <= HWLOC_OBJ_MISC; |
461 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc__obj_type_is_special Unexecuted instantiation: base64.c:hwloc__obj_type_is_special |
462 | | |
463 | | /* Any object attached to io children */ |
464 | | static __hwloc_inline int hwloc__obj_type_is_io (hwloc_obj_type_t type) |
465 | 0 | { |
466 | 0 | /* type contiguity is asserted in topology_check() */ |
467 | 0 | return type >= HWLOC_OBJ_BRIDGE && type <= HWLOC_OBJ_OS_DEVICE; |
468 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc__obj_type_is_io Unexecuted instantiation: base64.c:hwloc__obj_type_is_io |
469 | | |
470 | | /* Any CPU caches (not Memory-side caches) */ |
471 | | static __hwloc_inline int |
472 | | hwloc__obj_type_is_cache(hwloc_obj_type_t type) |
473 | 0 | { |
474 | 0 | /* type contiguity is asserted in topology_check() */ |
475 | 0 | return (type >= HWLOC_OBJ_L1CACHE && type <= HWLOC_OBJ_L3ICACHE); |
476 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc__obj_type_is_cache Unexecuted instantiation: base64.c:hwloc__obj_type_is_cache |
477 | | |
478 | | static __hwloc_inline int |
479 | | hwloc__obj_type_is_dcache(hwloc_obj_type_t type) |
480 | 0 | { |
481 | 0 | /* type contiguity is asserted in topology_check() */ |
482 | 0 | return (type >= HWLOC_OBJ_L1CACHE && type <= HWLOC_OBJ_L5CACHE); |
483 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc__obj_type_is_dcache Unexecuted instantiation: base64.c:hwloc__obj_type_is_dcache |
484 | | |
485 | | /** \brief Check whether an object is a Instruction Cache. */ |
486 | | static __hwloc_inline int |
487 | | hwloc__obj_type_is_icache(hwloc_obj_type_t type) |
488 | 0 | { |
489 | 0 | /* type contiguity is asserted in topology_check() */ |
490 | 0 | return (type >= HWLOC_OBJ_L1ICACHE && type <= HWLOC_OBJ_L3ICACHE); |
491 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc__obj_type_is_icache Unexecuted instantiation: base64.c:hwloc__obj_type_is_icache |
492 | | |
493 | | #ifdef HAVE_USELOCALE |
494 | | #include "locale.h" |
495 | | #ifdef HAVE_XLOCALE_H |
496 | | #include "xlocale.h" |
497 | | #endif |
498 | | #define hwloc_localeswitch_declare locale_t __old_locale = (locale_t)0, __new_locale |
499 | | #define hwloc_localeswitch_init() do { \ |
500 | | __new_locale = newlocale(LC_ALL_MASK, "C", (locale_t)0); \ |
501 | | if (__new_locale != (locale_t)0) \ |
502 | | __old_locale = uselocale(__new_locale); \ |
503 | | } while (0) |
504 | | #define hwloc_localeswitch_fini() do { \ |
505 | | if (__new_locale != (locale_t)0) { \ |
506 | | uselocale(__old_locale); \ |
507 | | freelocale(__new_locale); \ |
508 | | } \ |
509 | | } while(0) |
510 | | #else /* HAVE_USELOCALE */ |
511 | | #if HWLOC_HAVE_ATTRIBUTE_UNUSED |
512 | | #define hwloc_localeswitch_declare int __dummy_nolocale __hwloc_attribute_unused |
513 | | #define hwloc_localeswitch_init() |
514 | | #else |
515 | | #define hwloc_localeswitch_declare int __dummy_nolocale |
516 | | #define hwloc_localeswitch_init() (void)__dummy_nolocale |
517 | | #endif |
518 | | #define hwloc_localeswitch_fini() |
519 | | #endif /* HAVE_USELOCALE */ |
520 | | |
521 | | #if !HAVE_DECL_FABSF |
522 | | #define fabsf(f) fabs((double)(f)) |
523 | | #endif |
524 | | |
525 | | #if !HAVE_DECL_MODFF |
526 | | #define modff(x,iptr) (float)modf((double)x,(double *)iptr) |
527 | | #endif |
528 | | |
529 | | #if HAVE_DECL__SC_PAGE_SIZE |
530 | | #define hwloc_getpagesize() sysconf(_SC_PAGE_SIZE) |
531 | | #elif HAVE_DECL__SC_PAGESIZE |
532 | | #define hwloc_getpagesize() sysconf(_SC_PAGESIZE) |
533 | | #elif defined HAVE_GETPAGESIZE |
534 | | #define hwloc_getpagesize() getpagesize() |
535 | | #else |
536 | | #undef hwloc_getpagesize |
537 | | #endif |
538 | | |
539 | | #if HWLOC_HAVE_ATTRIBUTE_FORMAT |
540 | | # define __hwloc_attribute_format(type, str, arg) __attribute__((__format__(type, str, arg))) |
541 | | #else |
542 | | # define __hwloc_attribute_format(type, str, arg) |
543 | | #endif |
544 | | |
545 | | #ifdef HWLOC_WIN_SYS |
546 | | # ifndef HAVE_SSIZE_T |
547 | | typedef SSIZE_T ssize_t; |
548 | | # endif |
549 | | # if !HAVE_DECL_STRTOULL && !defined(HAVE_STRTOULL) |
550 | | # define strtoull _strtoui64 |
551 | | # endif |
552 | | # ifndef S_ISREG |
553 | | # define S_ISREG(m) ((m) & S_IFREG) |
554 | | # endif |
555 | | # ifndef S_ISDIR |
556 | | # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) |
557 | | # endif |
558 | | # ifndef S_IRWXU |
559 | | # define S_IRWXU 00700 |
560 | | # endif |
561 | | # ifndef HWLOC_HAVE_DECL_STRCASECMP |
562 | | # define strcasecmp _stricmp |
563 | | # endif |
564 | | # if !HAVE_DECL_SNPRINTF |
565 | | # define snprintf _snprintf |
566 | | # endif |
567 | | # if HAVE_DECL__STRDUP |
568 | | # define strdup _strdup |
569 | | # endif |
570 | | # if HAVE_DECL__PUTENV |
571 | | # define putenv _putenv |
572 | | # endif |
573 | | #endif |
574 | | |
575 | | static __inline float |
576 | | hwloc__pci_link_speed(unsigned generation, unsigned lanes) |
577 | 0 | { |
578 | 0 | float lanespeed; |
579 | 0 | /* |
580 | 0 | * These are single-direction bandwidths only. |
581 | 0 | * |
582 | 0 | * Gen1 used NRZ with 8/10 encoding. |
583 | 0 | * PCIe Gen1 = 2.5GT/s signal-rate per lane x 8/10 = 0.25GB/s data-rate per lane |
584 | 0 | * PCIe Gen2 = 5 GT/s signal-rate per lane x 8/10 = 0.5 GB/s data-rate per lane |
585 | 0 | * Gen3 switched to NRZ with 128/130 encoding. |
586 | 0 | * PCIe Gen3 = 8 GT/s signal-rate per lane x 128/130 = 1 GB/s data-rate per lane |
587 | 0 | * PCIe Gen4 = 16 GT/s signal-rate per lane x 128/130 = 2 GB/s data-rate per lane |
588 | 0 | * PCIe Gen5 = 32 GT/s signal-rate per lane x 128/130 = 4 GB/s data-rate per lane |
589 | 0 | * Gen6 switched to PAM with with 242/256 FLIT (242B payload protected by 8B CRC + 6B FEC). |
590 | 0 | * PCIe Gen6 = 64 GT/s signal-rate per lane x 242/256 = 8 GB/s data-rate per lane |
591 | 0 | * PCIe Gen7 = 128GT/s signal-rate per lane x 242/256 = 16 GB/s data-rate per lane |
592 | 0 | * PCIe Gen8 = 256GT/s signal-rate per lane x 242/256 = 32 GB/s date-rate per lane |
593 | 0 | * |
594 | 0 | * If future generations change encoding, topology-rsmi.c needs to be updated as well. |
595 | 0 | */ |
596 | 0 |
|
597 | 0 | /* lanespeed in Gbit/s */ |
598 | 0 | if (generation <= 2) |
599 | 0 | lanespeed = 2.5f * generation * 0.8f; |
600 | 0 | else if (generation <= 5) |
601 | 0 | lanespeed = 8.0f * (1<<(generation-3)) * 128/130; |
602 | 0 | else |
603 | 0 | lanespeed = 8.0f * (1<<(generation-3)) * 242/256; /* assume Gen9 will be 512 GT/s and so on */ |
604 | 0 |
|
605 | 0 | /* linkspeed in GB/s */ |
606 | 0 | return lanespeed * lanes / 8; |
607 | 0 | } Unexecuted instantiation: hwloc_fuzzer.c:hwloc__pci_link_speed Unexecuted instantiation: base64.c:hwloc__pci_link_speed |
608 | | |
609 | | #endif /* HWLOC_PRIVATE_MISC_H */ |