Coverage Report

Created: 2025-10-13 06:04

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