On 2/1/2012 11:46 AM, Paul H. Hargrove wrote:
[snip]
So, in short: when building w/ this compiler, hwloc needs to behave as
if the system lacks ffs().
Making that happen is non-trivial because there are no preprocessor
symbols defined by gccfss that would allow compile-time #if checks to
distinguish gccfss from "vanilla" gcc. The only difference is in the
string value of __VERSION__, which one could check at configure time.
Attached is a patch, relative to the svn trunk, which fixes this problem
in my testing.
As I outlined above, the approach is two-fold:
1) Add configure-time logic to ID the buggy compiler
2) Restructure include/private/misc.h to include a HWLOC_HAVE_BROKEN_FFS
case.
Two things I'd like to note about the approach:
+ The configure-time logic is NOT trying to determine the version
number, as I don't have a way (yet?) to pinpoint which version(s) work
correctly, and the Oracle Forums thread on the subject doesn't say. So,
it is conservatively assuming all "gccfss" versions are broken.
+ The misc.h changes are intentionally "generic" so one could add other
configure time checks to define HWLOC_HAVE_BROKEN_FFS based on problems
we've not yet discovered.
-Paul
--
Paul H. Hargrove phhargr...@lbl.gov
Future Technologies Group
HPC Research Department Tel: +1-510-495-2352
Lawrence Berkeley National Laboratory Fax: +1-510-486-6900
Index: include/private/misc.h
===================================================================
--- include/private/misc.h (revision 4239)
+++ include/private/misc.h (working copy)
@@ -46,8 +46,15 @@
* ffsl helpers.
*/
-#ifdef __GNUC__
+#if defined(HWLOC_HAVE_BROKEN_FFS)
+/* System has a broken ffs().
+ * We must check the before __GNUC__ or HWLOC_HAVE_FFSL
+ */
+# define HWLOC_NO_FFS
+
+#elif defined(__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)
@@ -75,6 +82,13 @@
#else /* no ffs implementation */
+# define HWLOC_NO_FFS
+
+#endif
+
+#ifdef HWLOC_NO_FFS
+
+/* no ffs or it is known to be broken */
static __hwloc_inline int __hwloc_attribute_const
hwloc_ffsl(unsigned long x)
{
@@ -114,10 +128,8 @@
return i;
}
-#endif
+#elif defined(HWLOC_NEED_FFSL)
-#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. */
Index: config/hwloc.m4
===================================================================
--- config/hwloc.m4 (revision 4239)
+++ config/hwloc.m4 (working copy)
@@ -446,6 +446,15 @@
AC_DEFINE([HWLOC_HAVE_DECL_FFS], [1], [Define to 1 if function `ffs'
is declared by system headers])
])
AC_DEFINE([HWLOC_HAVE_FFS], [1], [Define to 1 if you have the `ffs'
function.])
+ if ( $CC --version | grep gccfss ) >/dev/null 2>&1 ; then
+ dnl May be broken due to
+ dnl https://forums.oracle.com/forums/thread.jspa?threadID=1997328
+ dnl TODO: a more selective test, since bug may be version dependent.
+ dnl We can't use AC_TRY_LINK because the failure does not appear until
+ dnl run/load time and there is currently no precedent for AC_TRY_RUN
+ dnl use in hwloc. --PHH
+ AC_DEFINE([HWLOC_HAVE_BROKEN_FFS], [1], [Define to 1 if your `ffs'
function is known to be broken.])
+ fi
])
AC_CHECK_FUNCS([ffsl], [
_HWLOC_CHECK_DECL([ffsl],[