VERSION.sh | 2
config.h.in | 3
configure | 126 +++++++------------------------------
configure.ac | 13 +++
ldap/servers/slapd/slapi_counter.c | 75 ++++++++++++++++++++++
5 files changed, 114 insertions(+), 105 deletions(-)
New commits:
commit 9ad83ba1c311d15cb5b28d19702b2b307322ff76
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Jul 27 20:47:56 2011 -0600
bump version to 1.2.9.1
diff --git a/VERSION.sh b/VERSION.sh
index 9221119..314101e 100644
--- a/VERSION.sh
+++ b/VERSION.sh
@@ -10,7 +10,7 @@ vendor="389 Project"
# PACKAGE_VERSION is constructed from these
VERSION_MAJOR=1
VERSION_MINOR=2
-VERSION_MAINT=9.0
+VERSION_MAINT=9.1
# if this is a PRERELEASE, set VERSION_PREREL
# otherwise, comment it out
# be sure to include the dot prefix in the prerel
commit b9b1b3cdd8b4b964717e46ef4f34de6bcd3b085e
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Mon Aug 1 13:16:22 2011 -0600
Bug 723937 - replication failing on RUV errors
https://bugzilla.redhat.com/show_bug.cgi?id=723937
Resolves: bug 723937
Bug Description: replication failing on RUV errors
Reviewed by: nkinder (Thanks!)
Branch: master
Fix Description: The previous fix broke 32-bit i386 platforms. The Fedora
build systems use -march=i386. On those platforms, we have to use our own
assembler code. The fix is to introduce an AC_LINK_IFELSE test to
compile and link a short program using __sync_bool_compare_and_swap_8
during configure. If this succeeds, we just use the gcc builtin, otherwise,
we use our own asm code.
Platforms tested: RHEL6 x86_64, RHEL5 i386
Flag Day: no
Doc impact: no
This reverts commit c5bd90755da96f463ba5dfda79793d5d6cee4e53.
diff --git a/config.h.in b/config.h.in
index f65ac1c..888611a 100644
--- a/config.h.in
+++ b/config.h.in
@@ -67,8 +67,7 @@
don't. */
#undef HAVE_DECL_STRERROR_R
-/* Define to 1 if you have the declaration of `__sync_add_and_fetch', and to 0
- if you don't. */
+/* do not have 64-bit atomic compare and swap functions provided by gcc */
#undef HAVE_DECL___SYNC_ADD_AND_FETCH
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
diff --git a/configure b/configure
index 0039c6c..8ae9dca 100755
--- a/configure
+++ b/configure
@@ -20751,75 +20751,6 @@ cat >>confdefs.h <<\_ACEOF
#define ATOMIC_64BIT_OPERATIONS 1
_ACEOF
- { $as_echo "$as_me:$LINENO: checking whether __sync_add_and_fetch is
declared" >&5
-$as_echo_n "checking whether __sync_add_and_fetch is declared... " >&6;
}
-if test "${ac_cv_have_decl___sync_add_and_fetch+set}" = set; then
- $as_echo_n "(cached) " >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-#ifndef __sync_add_and_fetch
- (void) __sync_add_and_fetch;
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
-$as_echo "$ac_try_echo") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_have_decl___sync_add_and_fetch=yes
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_have_decl___sync_add_and_fetch=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:$LINENO: result: $ac_cv_have_decl___sync_add_and_fetch"
>&5
-$as_echo "$ac_cv_have_decl___sync_add_and_fetch" >&6; }
-if test "x$ac_cv_have_decl___sync_add_and_fetch" = x""yes; then
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL___SYNC_ADD_AND_FETCH 1
-_ACEOF
-
-
-else
- cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL___SYNC_ADD_AND_FETCH 0
-_ACEOF
-
-
-fi
-
-
;;
x86_64-*-linux*)
@@ -20832,38 +20763,34 @@ cat >>confdefs.h <<\_ACEOF
#define ATOMIC_64BIT_OPERATIONS 1
_ACEOF
- { $as_echo "$as_me:$LINENO: checking whether __sync_add_and_fetch is
declared" >&5
-$as_echo_n "checking whether __sync_add_and_fetch is declared... " >&6;
}
-if test "${ac_cv_have_decl___sync_add_and_fetch+set}" = set; then
- $as_echo_n "(cached) " >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
+ ;;
+ esac
+ { $as_echo "$as_me:$LINENO: checking for GCC provided 64-bit atomic
functions ..." >&5
+$as_echo_n "checking for GCC provided 64-bit atomic functions ...... "
>&6; }
+ cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-$ac_includes_default
+
int
main ()
{
-#ifndef __sync_add_and_fetch
- (void) __sync_add_and_fetch;
-#endif
-
+long long ptrval = 0, val = 0, newval = 1;
(void)__sync_bool_compare_and_swap_8(&ptrval, val, newval);
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
$as_echo "$ac_try_echo") >&5
- (eval "$ac_compile") 2>conftest.er1
+ (eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
@@ -20872,37 +20799,36 @@ $as_echo "$ac_try_echo") >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- ac_cv_have_decl___sync_add_and_fetch=yes
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ have_gcc_64bit_cas=1; { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
- ac_cv_have_decl___sync_add_and_fetch=no
+ have_gcc_64bit_cas=; { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:$LINENO: result: $ac_cv_have_decl___sync_add_and_fetch"
>&5
-$as_echo "$ac_cv_have_decl___sync_add_and_fetch" >&6; }
-if test "x$ac_cv_have_decl___sync_add_and_fetch" = x""yes; then
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -n "$have_gcc_64bit_cas" ; then
-cat >>confdefs.h <<_ACEOF
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL___SYNC_ADD_AND_FETCH 1
_ACEOF
+ else
-else
- cat >>confdefs.h <<_ACEOF
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL___SYNC_ADD_AND_FETCH 0
_ACEOF
-
-fi
-
-
- ;;
- esac
+ fi
# some programs use the native thread library directly
THREADLIB=-lpthread
THREADLIB=$THREADLIB
diff --git a/configure.ac b/configure.ac
index 3754867..ac4dc82 100644
--- a/configure.ac
+++ b/configure.ac
@@ -401,14 +401,23 @@ case $host in
i*86-*-linux*)
AC_DEFINE([CPU_x86], [], [cpu type x86])
AC_DEFINE([ATOMIC_64BIT_OPERATIONS], [1], [enabling atomic counter])
- AC_CHECK_DECLS([__sync_add_and_fetch])
;;
x86_64-*-linux*)
AC_DEFINE([CPU_x86_64], [], [cpu type x86_64])
AC_DEFINE([ATOMIC_64BIT_OPERATIONS], [1], [enabling atomic counter])
- AC_CHECK_DECLS([__sync_add_and_fetch])
;;
esac
+ dnl no headers to test for __sync_bool_compare_and_swap_8
+ AC_MSG_CHECKING([for GCC provided 64-bit atomic functions ...])
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],
+ [[long long ptrval = 0, val = 0, newval = 1;
(void)__sync_bool_compare_and_swap_8(&ptrval, val, newval);]])],
+ [have_gcc_64bit_cas=1; AC_MSG_RESULT([yes])],
+ [have_gcc_64bit_cas=; AC_MSG_RESULT([no])])
+ if test -n "$have_gcc_64bit_cas" ; then
+ AC_DEFINE([HAVE_DECL___SYNC_ADD_AND_FETCH], [1], [have 64-bit atomic compare and
swap functions provided by gcc])
+ else
+ AC_DEFINE([HAVE_DECL___SYNC_ADD_AND_FETCH], [0], [do not have 64-bit atomic
compare and swap functions provided by gcc])
+ fi
# some programs use the native thread library directly
THREADLIB=-lpthread
AC_SUBST([THREADLIB], [$THREADLIB])
diff --git a/ldap/servers/slapd/slapi_counter.c b/ldap/servers/slapd/slapi_counter.c
index a4476e5..c3f1f44 100644
--- a/ldap/servers/slapd/slapi_counter.c
+++ b/ldap/servers/slapd/slapi_counter.c
@@ -292,12 +292,49 @@ PRUint64 slapi_counter_set_value(Slapi_Counter *counter, PRUint64
newvalue)
return newvalue;
#else
#ifdef LINUX
+/* Use our own inline assembly for an atomic set if
+ * the builtins aren't available. */
+#if defined CPU_x86 || !HAVE_DECL___SYNC_ADD_AND_FETCH
+ /*
+ * %0 = counter->value
+ * %1 = newvalue
+ */
+ __asm__ __volatile__(
+#ifdef CPU_x86
+ /* Save the PIC register */
+ " pushl %%ebx;"
+#endif /* CPU_x86 */
+ /* Put value of counter->value in EDX:EAX */
+ "retryset: movl %0, %%eax;"
+ " movl 4%0, %%edx;"
+ /* Put newval in ECX:EBX */
+ " movl %1, %%ebx;"
+ " movl 4+%1, %%ecx;"
+ /* If EDX:EAX and counter-> are the same,
+ * replace *ptr with ECX:EBX */
+ " lock; cmpxchg8b %0;"
+ " jnz retryset;"
+#ifdef CPU_x86
+ /* Restore the PIC register */
+ " popl %%ebx"
+#endif /* CPU_x86 */
+ : "+o" (counter->value)
+ : "m" (newvalue)
+#ifdef CPU_x86
+ : "memory", "eax", "ecx", "edx",
"cc");
+#else
+ : "memory", "eax", "ebx", "ecx",
"edx", "cc");
+#endif
+
+ return newvalue;
+#else
while (1) {
value = counter->value;
if (__sync_bool_compare_and_swap(&(counter->value), value, newvalue)) {
return newvalue;
}
}
+#endif /* CPU_x86 || !HAVE_DECL___SYNC_ADD_AND_FETCH */
#elif defined(SOLARIS)
_sparcv9_AtomicSet(&(counter->value), newvalue);
return newvalue;
@@ -331,12 +368,50 @@ PRUint64 slapi_counter_get_value(Slapi_Counter *counter)
slapi_unlock_mutex(counter->lock);
#else
#ifdef LINUX
+/* Use our own inline assembly for an atomic get if
+ * the builtins aren't available. */
+#if defined CPU_x86 || !HAVE_DECL___SYNC_ADD_AND_FETCH
+ /*
+ * %0 = counter->value
+ * %1 = value
+ */
+ __asm__ __volatile__(
+#ifdef CPU_x86
+ /* Save the PIC register */
+ " pushl %%ebx;"
+#endif /* CPU_x86 */
+ /* Put value of counter->value in EDX:EAX */
+ "retryget: movl %0, %%eax;"
+ " movl 4%0, %%edx;"
+ /* Copy EDX:EAX to ECX:EBX */
+ " movl %%eax, %%ebx;"
+ " movl %%edx, %%ecx;"
+ /* If EDX:EAX and counter->value are the same,
+ * replace *ptr with ECX:EBX */
+ " lock; cmpxchg8b %0;"
+ " jnz retryget;"
+ /* Put retreived value into value */
+ " movl %%ebx, %1;"
+ " movl %%ecx, 4%1;"
+#ifdef CPU_x86
+ /* Restore the PIC register */
+ " popl %%ebx"
+#endif /* CPU_x86 */
+ : "+o" (counter->value), "=m" (value)
+ :
+#ifdef CPU_x86
+ : "memory", "eax", "ecx", "edx",
"cc");
+#else
+ : "memory", "eax", "ebx", "ecx",
"edx", "cc");
+#endif
+#else
while (1) {
value = counter->value;
if (__sync_bool_compare_and_swap(&(counter->value), value, value)) {
break;
}
}
+#endif /* CPU_x86 || !HAVE_DECL___SYNC_ADD_AND_FETCH */
#elif defined(SOLARIS)
while (1) {
value = counter->value;