root/opal/mca/hwloc/hwloc201/hwloc/include/private/misc.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. hwloc_ffsl_manual
  2. hwloc_ffs32
  3. hwloc_ffsl_from_ffs32
  4. hwloc_flsl_manual
  5. hwloc_fls32
  6. hwloc_flsl_from_fls32
  7. hwloc_weight_long
  8. hwloc_strncasecmp
  9. hwloc_cache_type_by_depth_type
  10. hwloc__obj_type_is_normal
  11. hwloc__obj_type_is_memory
  12. hwloc__obj_type_is_special
  13. hwloc__obj_type_is_io
  14. hwloc__obj_type_is_cache
  15. hwloc__obj_type_is_dcache
  16. hwloc__obj_type_is_icache

   1 /*
   2  * Copyright © 2009 CNRS
   3  * Copyright © 2009-2018 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 {
 338 #if HWLOC_BITS_PER_LONG == 32
 339 #if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__) >= 4)
 340         return __builtin_popcount(w);
 341 #else
 342         unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
 343         res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
 344         res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
 345         res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
 346         return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
 347 #endif
 348 #else /* HWLOC_BITS_PER_LONG == 32 */
 349 #if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__) >= 4)
 350         return __builtin_popcountll(w);
 351 #else
 352         unsigned long res;
 353         res = (w & 0x5555555555555555ul) + ((w >> 1) & 0x5555555555555555ul);
 354         res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
 355         res = (res & 0x0F0F0F0F0F0F0F0Ful) + ((res >> 4) & 0x0F0F0F0F0F0F0F0Ful);
 356         res = (res & 0x00FF00FF00FF00FFul) + ((res >> 8) & 0x00FF00FF00FF00FFul);
 357         res = (res & 0x0000FFFF0000FFFFul) + ((res >> 16) & 0x0000FFFF0000FFFFul);
 358         return (res & 0x00000000FFFFFFFFul) + ((res >> 32) & 0x00000000FFFFFFFFul);
 359 #endif
 360 #endif /* HWLOC_BITS_PER_LONG == 64 */
 361 }
 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 {
 369 #ifdef HWLOC_HAVE_DECL_STRNCASECMP
 370   return strncasecmp(s1, s2, n);
 371 #else
 372   while (n) {
 373     char c1 = tolower(*s1), c2 = tolower(*s2);
 374     if (!c1 || !c2 || c1 != c2)
 375       return c1-c2;
 376     n--; s1++; s2++;
 377   }
 378   return 0;
 379 #endif
 380 }
 381 
 382 static __hwloc_inline hwloc_obj_type_t hwloc_cache_type_by_depth_type(unsigned depth, hwloc_obj_cache_type_t type)
 383 {
 384   if (type == HWLOC_OBJ_CACHE_INSTRUCTION) {
 385     if (depth >= 1 && depth <= 3)
 386       return HWLOC_OBJ_L1ICACHE + depth-1;
 387     else
 388       return HWLOC_OBJ_TYPE_NONE;
 389   } else {
 390     if (depth >= 1 && depth <= 5)
 391       return HWLOC_OBJ_L1CACHE + depth-1;
 392     else
 393       return HWLOC_OBJ_TYPE_NONE;
 394   }
 395 }
 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 /* Traverse children of a parent */
 410 #define for_each_child(child, parent) for(child = parent->first_child; child; child = child->next_sibling)
 411 #define for_each_memory_child(child, parent) for(child = parent->memory_first_child; child; child = child->next_sibling)
 412 #define for_each_io_child(child, parent) for(child = parent->io_first_child; child; child = child->next_sibling)
 413 #define for_each_misc_child(child, parent) for(child = parent->misc_first_child; child; child = child->next_sibling)
 414 
 415 /* Any object attached to normal children */
 416 static __hwloc_inline int hwloc__obj_type_is_normal (hwloc_obj_type_t type)
 417 {
 418   /* type contiguity is asserted in topology_check() */
 419   return type <= HWLOC_OBJ_GROUP;
 420 }
 421 
 422 /* Any object attached to memory children, currently only NUMA nodes */
 423 static __hwloc_inline int hwloc__obj_type_is_memory (hwloc_obj_type_t type)
 424 {
 425   /* type contiguity is asserted in topology_check() */
 426   return type == HWLOC_OBJ_NUMANODE;
 427 }
 428 
 429 /* I/O or Misc object, without cpusets or nodesets. */
 430 static __hwloc_inline int hwloc__obj_type_is_special (hwloc_obj_type_t type)
 431 {
 432   /* type contiguity is asserted in topology_check() */
 433   return type >= HWLOC_OBJ_BRIDGE && type <= HWLOC_OBJ_MISC;
 434 }
 435 
 436 /* Any object attached to io children */
 437 static __hwloc_inline int hwloc__obj_type_is_io (hwloc_obj_type_t type)
 438 {
 439   /* type contiguity is asserted in topology_check() */
 440   return type >= HWLOC_OBJ_BRIDGE && type <= HWLOC_OBJ_OS_DEVICE;
 441 }
 442 
 443 static __hwloc_inline int
 444 hwloc__obj_type_is_cache(hwloc_obj_type_t type)
 445 {
 446   /* type contiguity is asserted in topology_check() */
 447   return (type >= HWLOC_OBJ_L1CACHE && type <= HWLOC_OBJ_L3ICACHE);
 448 }
 449 
 450 static __hwloc_inline int
 451 hwloc__obj_type_is_dcache(hwloc_obj_type_t type)
 452 {
 453   /* type contiguity is asserted in topology_check() */
 454   return (type >= HWLOC_OBJ_L1CACHE && type <= HWLOC_OBJ_L5CACHE);
 455 }
 456 
 457 /** \brief Check whether an object is a Instruction Cache. */
 458 static __hwloc_inline int
 459 hwloc__obj_type_is_icache(hwloc_obj_type_t type)
 460 {
 461   /* type contiguity is asserted in topology_check() */
 462   return (type >= HWLOC_OBJ_L1ICACHE && type <= HWLOC_OBJ_L3ICACHE);
 463 }
 464 
 465 #ifdef HAVE_USELOCALE
 466 #include "locale.h"
 467 #ifdef HAVE_XLOCALE_H
 468 #include "xlocale.h"
 469 #endif
 470 #define hwloc_localeswitch_declare locale_t __old_locale = (locale_t)0, __new_locale
 471 #define hwloc_localeswitch_init() do {                     \
 472   __new_locale = newlocale(LC_ALL_MASK, "C", (locale_t)0); \
 473   if (__new_locale != (locale_t)0)                         \
 474     __old_locale = uselocale(__new_locale);                \
 475 } while (0)
 476 #define hwloc_localeswitch_fini() do { \
 477   if (__new_locale != (locale_t)0) {   \
 478     uselocale(__old_locale);           \
 479     freelocale(__new_locale);          \
 480   }                                    \
 481 } while(0)
 482 #else /* HAVE_USELOCALE */
 483 #if __HWLOC_HAVE_ATTRIBUTE_UNUSED
 484 #define hwloc_localeswitch_declare int __dummy_nolocale __hwloc_attribute_unused
 485 #define hwloc_localeswitch_init()
 486 #else
 487 #define hwloc_localeswitch_declare int __dummy_nolocale
 488 #define hwloc_localeswitch_init() (void)__dummy_nolocale
 489 #endif
 490 #define hwloc_localeswitch_fini()
 491 #endif /* HAVE_USELOCALE */
 492 
 493 #if !HAVE_DECL_FABSF
 494 #define fabsf(f) fabs((double)(f))
 495 #endif
 496 
 497 #if HAVE_DECL__SC_PAGE_SIZE
 498 #define hwloc_getpagesize() sysconf(_SC_PAGE_SIZE)
 499 #elif HAVE_DECL__SC_PAGESIZE
 500 #define hwloc_getpagesize() sysconf(_SC_PAGESIZE)
 501 #elif defined HAVE_GETPAGESIZE
 502 #define hwloc_getpagesize() getpagesize()
 503 #else
 504 #undef hwloc_getpagesize
 505 #endif
 506 
 507 #if HWLOC_HAVE_ATTRIBUTE_FORMAT
 508 #  define __hwloc_attribute_format(type, str, arg)  __attribute__((__format__(type, str, arg)))
 509 #else
 510 #  define __hwloc_attribute_format(type, str, arg)
 511 #endif
 512 
 513 #define hwloc_memory_size_printf_value(_size, _verbose) \
 514   ((_size) < (10ULL<<20) || _verbose ? (((_size)>>9)+1)>>1 : (_size) < (10ULL<<30) ? (((_size)>>19)+1)>>1 : (_size) < (10ULL<<40) ? (((_size)>>29)+1)>>1 : (((_size)>>39)+1)>>1)
 515 #define hwloc_memory_size_printf_unit(_size, _verbose) \
 516   ((_size) < (10ULL<<20) || _verbose ? "KB" : (_size) < (10ULL<<30) ? "MB" : (_size) < (10ULL<<40) ? "GB" : "TB")
 517 
 518 #ifdef HWLOC_WIN_SYS
 519 #  ifndef HAVE_SSIZE_T
 520 typedef SSIZE_T ssize_t;
 521 #  endif
 522 #  if !HAVE_DECL_STRTOULL && !defined(HAVE_STRTOULL)
 523 #    define strtoull _strtoui64
 524 #  endif
 525 #  ifndef S_ISREG
 526 #    define S_ISREG(m) ((m) & S_IFREG)
 527 #  endif
 528 #  ifndef S_ISDIR
 529 #    define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
 530 #  endif
 531 #  if !HAVE_DECL_STRCASECMP
 532 #    define strcasecmp _stricmp
 533 #  endif
 534 #  if !HAVE_DECL_SNPRINTF
 535 #    define snprintf _snprintf
 536 #  endif
 537 #  if HAVE_DECL__STRDUP
 538 #    define strdup _strdup
 539 #  endif
 540 #  if HAVE_DECL__PUTENV
 541 #    define putenv _putenv
 542 #  endif
 543 #endif
 544 
 545 #if defined HWLOC_WIN_SYS && !defined __MINGW32__
 546 /* MSVC doesn't support C99 variable-length array */
 547 #include <malloc.h>
 548 #define HWLOC_VLA(_type, _name, _nb) _type *_name = (_type*) _alloca((_nb)*sizeof(_type))
 549 #else
 550 #define HWLOC_VLA(_type, _name, _nb) _type _name[_nb]
 551 #endif
 552 
 553 #endif /* HWLOC_PRIVATE_MISC_H */

/* [<][>][^][v][top][bottom][index][help] */