Coverage Report

Created: 2025-08-29 06:04

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