Coverage Report

Created: 2026-09-28 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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 */