summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config.h.in10
-rwxr-xr-xconfigure201
-rw-r--r--configure.ac19
-rw-r--r--ldap/servers/slapd/result.c4
-rw-r--r--ldap/servers/slapd/slapi_counter.c186
-rw-r--r--ldap/servers/snmp/ldap-agent.h5
6 files changed, 420 insertions, 5 deletions
diff --git a/config.h.in b/config.h.in
index 45827279..d3febbb5 100644
--- a/config.h.in
+++ b/config.h.in
@@ -15,6 +15,12 @@
/* cpu type sparc */
#undef CPU_sparc
+/* cpu type x86 */
+#undef CPU_x86
+
+/* cpu type x86_64 */
+#undef CPU_x86_64
+
/* enable ldapi auto bind support in the server */
#undef ENABLE_AUTOBIND
@@ -43,6 +49,10 @@
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. */
+#undef HAVE_DECL___SYNC_ADD_AND_FETCH
+
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#undef HAVE_DIRENT_H
diff --git a/configure b/configure
index d02bc3b0..9b8bd2fe 100755
--- a/configure
+++ b/configure
@@ -23358,7 +23358,7 @@ initdir=/rc.d
# those with our 64 bit compiled product.
perlexec='/usr/bin/env perl'
case $host in
- *-*-linux*)
+ i*86-*-linux*)
cat >>confdefs.h <<\_ACEOF
#define XP_UNIX 1
@@ -23391,6 +23391,133 @@ _ACEOF
cat >>confdefs.h <<\_ACEOF
+#define CPU_x86
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define _GNU_SOURCE 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define ATOMIC_64BIT_OPERATIONS 1
+_ACEOF
+
+ echo "$as_me:$LINENO: checking whether __sync_add_and_fetch is declared" >&5
+echo $ECHO_N "checking whether __sync_add_and_fetch is declared... $ECHO_C" >&6
+if test "${ac_cv_have_decl___sync_add_and_fetch+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&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
+ char *p = (char *) __sync_add_and_fetch;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_have_decl___sync_add_and_fetch=yes
+else
+ 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 conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_decl___sync_add_and_fetch" >&5
+echo "${ECHO_T}$ac_cv_have_decl___sync_add_and_fetch" >&6
+if test $ac_cv_have_decl___sync_add_and_fetch = 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
+
+
+ platform="linux"
+ # relative to sysconfdir
+ initdir=/rc.d/init.d
+ ;;
+ x86_64-*-linux*)
+
+cat >>confdefs.h <<\_ACEOF
+#define XP_UNIX 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define Linux 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define LINUX 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define LINUX2_0 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define LINUX2_2 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define LINUX2_4 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define CPU_x86_64
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
#define _GNU_SOURCE 1
_ACEOF
@@ -23399,6 +23526,78 @@ cat >>confdefs.h <<\_ACEOF
#define ATOMIC_64BIT_OPERATIONS 1
_ACEOF
+ echo "$as_me:$LINENO: checking whether __sync_add_and_fetch is declared" >&5
+echo $ECHO_N "checking whether __sync_add_and_fetch is declared... $ECHO_C" >&6
+if test "${ac_cv_have_decl___sync_add_and_fetch+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&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
+ char *p = (char *) __sync_add_and_fetch;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_have_decl___sync_add_and_fetch=yes
+else
+ 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 conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_decl___sync_add_and_fetch" >&5
+echo "${ECHO_T}$ac_cv_have_decl___sync_add_and_fetch" >&6
+if test $ac_cv_have_decl___sync_add_and_fetch = 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
+
+
platform="linux"
# relative to sysconfdir
initdir=/rc.d/init.d
diff --git a/configure.ac b/configure.ac
index ca0bd20c..fc8d7246 100644
--- a/configure.ac
+++ b/configure.ac
@@ -294,15 +294,32 @@ initdir=/rc.d
# those with our 64 bit compiled product.
perlexec='/usr/bin/env perl'
case $host in
- *-*-linux*)
+ i*86-*-linux*)
AC_DEFINE([XP_UNIX], [1], [UNIX])
AC_DEFINE([Linux], [1], [Linux])
AC_DEFINE([LINUX], [1], [Linux])
AC_DEFINE([LINUX2_0], [1], [Linux 2.0])
AC_DEFINE([LINUX2_2], [1], [Linux 2.2])
AC_DEFINE([LINUX2_4], [1], [Linux 2.4])
+ AC_DEFINE([CPU_x86], [], [cpu type x86])
AC_DEFINE([_GNU_SOURCE], [1], [GNU Source])
AC_DEFINE([ATOMIC_64BIT_OPERATIONS], [1], [enabling atomic counter])
+ AC_CHECK_DECLS([__sync_add_and_fetch])
+ platform="linux"
+ # relative to sysconfdir
+ initdir=/rc.d/init.d
+ ;;
+ x86_64-*-linux*)
+ AC_DEFINE([XP_UNIX], [1], [UNIX])
+ AC_DEFINE([Linux], [1], [Linux])
+ AC_DEFINE([LINUX], [1], [Linux])
+ AC_DEFINE([LINUX2_0], [1], [Linux 2.0])
+ AC_DEFINE([LINUX2_2], [1], [Linux 2.2])
+ AC_DEFINE([LINUX2_4], [1], [Linux 2.4])
+ AC_DEFINE([CPU_x86_64], [], [cpu type x86_64])
+ AC_DEFINE([_GNU_SOURCE], [1], [GNU Source])
+ AC_DEFINE([ATOMIC_64BIT_OPERATIONS], [1], [enabling atomic counter])
+ AC_CHECK_DECLS([__sync_add_and_fetch])
platform="linux"
# relative to sysconfdir
initdir=/rc.d/init.d
diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
index 387353e4..e07ad7a3 100644
--- a/ldap/servers/slapd/result.c
+++ b/ldap/servers/slapd/result.c
@@ -60,8 +60,8 @@
#include <ssl.h>
-Slapi_Counter *num_entries_sent;
-Slapi_Counter *num_bytes_sent;
+static Slapi_Counter *num_entries_sent;
+static Slapi_Counter *num_bytes_sent;
static long current_conn_count;
static PRLock *current_conn_count_mutex;
diff --git a/ldap/servers/slapd/slapi_counter.c b/ldap/servers/slapd/slapi_counter.c
index d5812dc9..a3886eb3 100644
--- a/ldap/servers/slapd/slapi_counter.c
+++ b/ldap/servers/slapd/slapi_counter.c
@@ -52,6 +52,24 @@ PRUint64 _sparcv9_AtomicSub_il(PRUint64 *address, PRUint64 val);
#include <machine/sys/inline.h>
#endif
#endif
+
+#if defined LINUX && (defined CPU_x86 || !HAVE_DECL___SYNC_ADD_AND_FETCH)
+/* On systems that don't have the 64-bit GCC atomic builtins, we need to
+ * implement our own atomic functions using inline assembly code. */
+static PRUint64 __sync_add_and_fetch_8(PRUint64 *ptr, PRUint64 addval);
+static PRUint64 __sync_sub_and_fetch_8(PRUint64 *ptr, PRUint64 subval);
+#endif
+
+#if defined LINUX && !HAVE_DECL___SYNC_ADD_AND_FETCH
+/* Systems that have the atomic builtins defined, but don't have
+ * implementations for 64-bit values will automatically try to
+ * call the __sync_*_8 versions we provide. If the atomic builtins
+ * are not defined at all, we define them here to use our local
+ * functions. */
+#define __sync_add_and_fetch __sync_add_and_fetch_8
+#define __sync_sub_and_fetch __sync_sub_and_fetch_8
+#endif
+
/*
* Counter Structure
*/
@@ -271,12 +289,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;
@@ -310,12 +365,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;
@@ -334,3 +427,96 @@ PRUint64 slapi_counter_get_value(Slapi_Counter *counter)
return value;
}
+
+#if defined LINUX && (defined CPU_x86 || !HAVE_DECL___SYNC_ADD_AND_FETCH)
+/* On systems that don't have the 64-bit GCC atomic builtins, we need to
+ * implement our own atomic add and subtract functions using inline
+ * assembly code. */
+static PRUint64 __sync_add_and_fetch_8(PRUint64 *ptr, PRUint64 addval)
+{
+ PRUint64 retval = 0;
+
+ /*
+ * %0 = *ptr
+ * %1 = retval
+ * %2 = addval
+ */
+ __asm__ __volatile__(
+#ifdef CPU_x86
+ /* Save the PIC register */
+ " pushl %%ebx;"
+#endif /* CPU_x86 */
+ /* Put value of *ptr in EDX:EAX */
+ "retryadd: movl %0, %%eax;"
+ " movl 4%0, %%edx;"
+ /* Put addval in ECX:EBX */
+ " movl %2, %%ebx;"
+ " movl 4%2, %%ecx;"
+ /* Add value from EDX:EAX to value in ECX:EBX */
+ " addl %%eax, %%ebx;"
+ " adcl %%edx, %%ecx;"
+ /* If EDX:EAX and *ptr are the same, replace ptr with ECX:EBX */
+ " lock; cmpxchg8b %0;"
+ " jnz retryadd;"
+ /* Put new value into retval */
+ " movl %%ebx, %1;"
+ " movl %%ecx, 4%1;"
+#ifdef CPU_x86
+ /* Restore the PIC register */
+ " popl %%ebx"
+#endif /* CPU_x86 */
+ : "+o" (*ptr), "=m" (retval)
+ : "m" (addval)
+#ifdef CPU_x86
+ : "memory", "eax", "ecx", "edx", "cc");
+#else
+ : "memory", "eax", "ebx", "ecx", "edx", "cc");
+#endif
+
+ return retval;
+}
+
+static PRUint64 __sync_sub_and_fetch_8(PRUint64 *ptr, PRUint64 subval)
+{
+ PRUint64 retval = 0;
+
+ /*
+ * %0 = *ptr
+ * %1 = retval
+ * %2 = subval
+ */
+ __asm__ __volatile__(
+#ifdef CPU_x86
+ /* Save the PIC register */
+ " pushl %%ebx;"
+#endif /* CPU_x86 */
+ /* Put value of *ptr in EDX:EAX */
+ "retrysub: movl %0, %%eax;"
+ " movl 4%0, %%edx;"
+ /* Copy EDX:EAX to ECX:EBX */
+ " movl %%eax, %%ebx;"
+ " movl %%edx, %%ecx;"
+ /* Subtract subval from value in ECX:EBX */
+ " subl %2, %%ebx;"
+ " sbbl 4%2, %%ecx;"
+ /* If EDX:EAX and ptr are the same, replace *ptr with ECX:EBX */
+ " lock; cmpxchg8b %0;"
+ " jnz retrysub;"
+ /* Put new value into retval */
+ " movl %%ebx, %1;"
+ " movl %%ecx, 4%1;"
+#ifdef CPU_x86
+ /* Restore the PIC register */
+ " popl %%ebx"
+#endif /* CPU_x86 */
+ : "+o" (*ptr), "=m" (retval)
+ : "m" (subval)
+#ifdef CPU_x86
+ : "memory", "eax", "ecx", "edx", "cc");
+#else
+ : "memory", "eax", "ebx", "ecx", "edx", "cc");
+#endif
+
+ return retval;
+}
+#endif /* LINUX && (defined CPU_x86 || !HAVE_DECL___SYNC_ADD_AND_FETCH) */
diff --git a/ldap/servers/snmp/ldap-agent.h b/ldap/servers/snmp/ldap-agent.h
index cb7a395d..30253d1c 100644
--- a/ldap/servers/snmp/ldap-agent.h
+++ b/ldap/servers/snmp/ldap-agent.h
@@ -79,7 +79,10 @@ extern "C" {
#ifdef HPUX
/* HP-UX doesn't define SEM_FAILED like other platforms, so
- * * we define it ourselves. */
+ * we define it ourselves. We make this define HP-UX specific
+ * since sem_open() doesn't seem to return the same value on
+ * all platforms in a failure case (it's 1 on some platforms,
+ * and 0 on others). */
#define SEM_FAILED ((sem_t *)(-1))
#endif