summaryrefslogtreecommitdiffstats
path: root/hwloc-1.2.1/include/private/misc.h
diff options
context:
space:
mode:
Diffstat (limited to 'hwloc-1.2.1/include/private/misc.h')
-rw-r--r--hwloc-1.2.1/include/private/misc.h331
1 files changed, 331 insertions, 0 deletions
diff --git a/hwloc-1.2.1/include/private/misc.h b/hwloc-1.2.1/include/private/misc.h
new file mode 100644
index 00000000..7fb21fca
--- /dev/null
+++ b/hwloc-1.2.1/include/private/misc.h
@@ -0,0 +1,331 @@
+/*
+ * Copyright © 2009 CNRS
+ * Copyright © 2009-2010 INRIA. All rights reserved.
+ * Copyright © 2009-2011 Université Bordeaux 1
+ * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
+ * See COPYING in top-level directory.
+ */
+
+/* Misc internals routines. */
+
+#ifndef HWLOC_PRIVATE_MISC_H
+#define HWLOC_PRIVATE_MISC_H
+
+#include <hwloc/autogen/config.h>
+#include <private/autogen/config.h>
+#include <private/private.h>
+
+
+/* On some systems, snprintf returns the size of written data, not the actually
+ * required size. hwloc_snprintf always report the actually required size. */
+int hwloc_snprintf(char *str, size_t size, const char *format, ...) __hwloc_attribute_format(printf, 3, 4);
+
+/* Check whether needle matches the beginning of haystack, at least n, and up
+ * to a colon or \0 */
+HWLOC_DECLSPEC
+int hwloc_namecoloncmp(const char *haystack, const char *needle, size_t n);
+
+/* Compile-time assertion */
+#define HWLOC_BUILD_ASSERT(condition) ((void)sizeof(char[1 - 2*!(condition)]))
+
+
+
+#define HWLOC_BITS_PER_LONG (HWLOC_SIZEOF_UNSIGNED_LONG * 8)
+#define HWLOC_BITS_PER_INT (HWLOC_SIZEOF_UNSIGNED_INT * 8)
+
+#if (HWLOC_BITS_PER_LONG != 32) && (HWLOC_BITS_PER_LONG != 64)
+#error "unknown size for unsigned long."
+#endif
+
+#if (HWLOC_BITS_PER_INT != 16) && (HWLOC_BITS_PER_INT != 32) && (HWLOC_BITS_PER_INT != 64)
+#error "unknown size for unsigned int."
+#endif
+
+
+/**
+ * ffsl helpers.
+ */
+
+#ifdef __GNUC__
+
+# if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))
+ /* Starting from 3.4, gcc has a long variant. */
+# define hwloc_ffsl(x) __builtin_ffsl(x)
+# else
+# define hwloc_ffs(x) __builtin_ffs(x)
+# define HWLOC_NEED_FFSL
+# endif
+
+#elif defined(HWLOC_HAVE_FFSL)
+
+# ifndef HWLOC_HAVE_DECL_FFSL
+extern int ffsl(long) __hwloc_attribute_const;
+# endif
+
+# define hwloc_ffsl(x) ffsl(x)
+
+#elif defined(HWLOC_HAVE_FFS)
+
+# ifndef HWLOC_HAVE_DECL_FFS
+extern int ffs(int) __hwloc_attribute_const;
+# endif
+
+# define hwloc_ffs(x) ffs(x)
+# define HWLOC_NEED_FFSL
+
+#else /* no ffs implementation */
+
+static __hwloc_inline int __hwloc_attribute_const
+hwloc_ffsl(unsigned long x)
+{
+ int i;
+
+ if (!x)
+ return 0;
+
+ i = 1;
+#if HWLOC_BITS_PER_LONG >= 64
+ if (!(x & 0xfffffffful)) {
+ x >>= 32;
+ i += 32;
+ }
+#endif
+ if (!(x & 0xffffu)) {
+ x >>= 16;
+ i += 16;
+ }
+ if (!(x & 0xff)) {
+ x >>= 8;
+ i += 8;
+ }
+ if (!(x & 0xf)) {
+ x >>= 4;
+ i += 4;
+ }
+ if (!(x & 0x3)) {
+ x >>= 2;
+ i += 2;
+ }
+ if (!(x & 0x1)) {
+ x >>= 1;
+ i += 1;
+ }
+
+ return i;
+}
+
+#endif
+
+#ifdef HWLOC_NEED_FFSL
+
+/* We only have an int ffs(int) implementation, build a long one. */
+
+/* First make it 32 bits if it was only 16. */
+static __hwloc_inline int __hwloc_attribute_const
+hwloc_ffs32(unsigned long x)
+{
+#if HWLOC_BITS_PER_INT == 16
+ int low_ffs, hi_ffs;
+
+ low_ffs = hwloc_ffs(x & 0xfffful);
+ if (low_ffs)
+ return low_ffs;
+
+ hi_ffs = hwloc_ffs(x >> 16);
+ if (hi_ffs)
+ return hi_ffs + 16;
+
+ return 0;
+#else
+ return hwloc_ffs(x);
+#endif
+}
+
+/* Then make it 64 bit if longs are. */
+static __hwloc_inline int __hwloc_attribute_const
+hwloc_ffsl(unsigned long x)
+{
+#if HWLOC_BITS_PER_LONG == 64
+ int low_ffs, hi_ffs;
+
+ low_ffs = hwloc_ffs32(x & 0xfffffffful);
+ if (low_ffs)
+ return low_ffs;
+
+ hi_ffs = hwloc_ffs32(x >> 32);
+ if (hi_ffs)
+ return hi_ffs + 32;
+
+ return 0;
+#else
+ return hwloc_ffs32(x);
+#endif
+}
+#endif
+
+/**
+ * flsl helpers.
+ */
+#ifdef __GNUC_____
+
+# if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))
+# define hwloc_flsl(x) (x ? 8*sizeof(long) - __builtin_clzl(x) : 0)
+# else
+# define hwloc_fls(x) (x ? 8*sizeof(int) - __builtin_clz(x) : 0)
+# define HWLOC_NEED_FLSL
+# endif
+
+#elif defined(HWLOC_HAVE_FLSL)
+
+# ifndef HWLOC_HAVE_DECL_FLSL
+extern int flsl(long) __hwloc_attribute_const;
+# endif
+
+# define hwloc_flsl(x) flsl(x)
+
+#elif defined(HWLOC_HAVE_CLZL)
+
+# ifndef HWLOC_HAVE_DECL_CLZL
+extern int clzl(long) __hwloc_attribute_const;
+# endif
+
+# define hwloc_flsl(x) (x ? 8*sizeof(long) - clzl(x) : 0)
+
+#elif defined(HWLOC_HAVE_FLS)
+
+# ifndef HWLOC_HAVE_DECL_FLS
+extern int fls(int) __hwloc_attribute_const;
+# endif
+
+# define hwloc_fls(x) fls(x)
+# define HWLOC_NEED_FLSL
+
+#elif defined(HWLOC_HAVE_CLZ)
+
+# ifndef HWLOC_HAVE_DECL_CLZ
+extern int clz(int) __hwloc_attribute_const;
+# endif
+
+# define hwloc_fls(x) (x ? 8*sizeof(int) - clz(x) : 0)
+# define HWLOC_NEED_FLSL
+
+#else /* no fls implementation */
+
+static __hwloc_inline int __hwloc_attribute_const
+hwloc_flsl(unsigned long x)
+{
+ int i = 0;
+
+ if (!x)
+ return 0;
+
+ i = 1;
+#if HWLOC_BITS_PER_LONG >= 64
+ if ((x & 0xffffffff00000000ul)) {
+ x >>= 32;
+ i += 32;
+ }
+#endif
+ if ((x & 0xffff0000u)) {
+ x >>= 16;
+ i += 16;
+ }
+ if ((x & 0xff00)) {
+ x >>= 8;
+ i += 8;
+ }
+ if ((x & 0xf0)) {
+ x >>= 4;
+ i += 4;
+ }
+ if ((x & 0xc)) {
+ x >>= 2;
+ i += 2;
+ }
+ if ((x & 0x2)) {
+ x >>= 1;
+ i += 1;
+ }
+
+ return i;
+}
+
+#endif
+
+#ifdef HWLOC_NEED_FLSL
+
+/* We only have an int fls(int) implementation, build a long one. */
+
+/* First make it 32 bits if it was only 16. */
+static __hwloc_inline int __hwloc_attribute_const
+hwloc_fls32(unsigned long x)
+{
+#if HWLOC_BITS_PER_INT == 16
+ int low_fls, hi_fls;
+
+ hi_fls = hwloc_fls(x >> 16);
+ if (hi_fls)
+ return hi_fls + 16;
+
+ low_fls = hwloc_fls(x & 0xfffful);
+ if (low_fls)
+ return low_fls;
+
+ return 0;
+#else
+ return hwloc_fls(x);
+#endif
+}
+
+/* Then make it 64 bit if longs are. */
+static __hwloc_inline int __hwloc_attribute_const
+hwloc_flsl(unsigned long x)
+{
+#if HWLOC_BITS_PER_LONG == 64
+ int low_fls, hi_fls;
+
+ hi_fls = hwloc_fls32(x >> 32);
+ if (hi_fls)
+ return hi_fls + 32;
+
+ low_fls = hwloc_fls32(x & 0xfffffffful);
+ if (low_fls)
+ return low_fls;
+
+ return 0;
+#else
+ return hwloc_fls32(x);
+#endif
+}
+#endif
+
+static __hwloc_inline int __hwloc_attribute_const
+hwloc_weight_long(unsigned long w)
+{
+#if HWLOC_BITS_PER_LONG == 32
+#if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__) >= 4)
+ return __builtin_popcount(w);
+#else
+ unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
+ res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
+ res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
+ res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
+ return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
+#endif
+#else /* HWLOC_BITS_PER_LONG == 32 */
+#if (__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__) >= 4)
+ return __builtin_popcountll(w);
+#else
+ unsigned long res;
+ res = (w & 0x5555555555555555ul) + ((w >> 1) & 0x5555555555555555ul);
+ res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
+ res = (res & 0x0F0F0F0F0F0F0F0Ful) + ((res >> 4) & 0x0F0F0F0F0F0F0F0Ful);
+ res = (res & 0x00FF00FF00FF00FFul) + ((res >> 8) & 0x00FF00FF00FF00FFul);
+ res = (res & 0x0000FFFF0000FFFFul) + ((res >> 16) & 0x0000FFFF0000FFFFul);
+ return (res & 0x00000000FFFFFFFFul) + ((res >> 32) & 0x00000000FFFFFFFFul);
+#endif
+#endif /* HWLOC_BITS_PER_LONG == 64 */
+}
+
+
+#endif /* HWLOC_PRIVATE_MISC_H */