You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by da...@apache.org on 2007/07/10 18:35:47 UTC
svn commit: r554995 - in /apr/apr/trunk: atomic/netware/apr_atomic.c
atomic/unix/builtins.c atomic/unix/ia32.c atomic/unix/mutex.c
atomic/unix/ppc.c atomic/unix/s390.c atomic/unix/solaris.c
atomic/win32/apr_atomic.c include/apr_atomic.h test/testatomic.c
Author: davi
Date: Tue Jul 10 09:35:45 2007
New Revision: 554995
URL: http://svn.apache.org/viewvc?view=rev&rev=554995
Log:
Introduce apr_atomic_xchgptr, which atomically exchanges a pair of pointer
values. Missing OS/390 implementation.
Modified:
apr/apr/trunk/atomic/netware/apr_atomic.c
apr/apr/trunk/atomic/unix/builtins.c
apr/apr/trunk/atomic/unix/ia32.c
apr/apr/trunk/atomic/unix/mutex.c
apr/apr/trunk/atomic/unix/ppc.c
apr/apr/trunk/atomic/unix/s390.c
apr/apr/trunk/atomic/unix/solaris.c
apr/apr/trunk/atomic/win32/apr_atomic.c
apr/apr/trunk/include/apr_atomic.h
apr/apr/trunk/test/testatomic.c
Modified: apr/apr/trunk/atomic/netware/apr_atomic.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/atomic/netware/apr_atomic.c?view=diff&rev=554995&r1=554994&r2=554995
==============================================================================
--- apr/apr/trunk/atomic/netware/apr_atomic.c (original)
+++ apr/apr/trunk/atomic/netware/apr_atomic.c Tue Jul 10 09:35:45 2007
@@ -68,3 +68,8 @@
{
return (void*)atomic_cmpxchg((unsigned long *)mem,(unsigned long)cmp,(unsigned long)with);
}
+
+APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with)
+{
+ return (void*)atomic_xchg((unsigned long *)mem,(unsigned long)with);
+}
Modified: apr/apr/trunk/atomic/unix/builtins.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/atomic/unix/builtins.c?view=diff&rev=554995&r1=554994&r2=554995
==============================================================================
--- apr/apr/trunk/atomic/unix/builtins.c (original)
+++ apr/apr/trunk/atomic/unix/builtins.c Tue Jul 10 09:35:45 2007
@@ -71,4 +71,11 @@
return (void*) __sync_val_compare_and_swap(mem, cmp, with);
}
+APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with)
+{
+ __sync_synchronize();
+
+ return (void*) __sync_lock_test_and_set(mem, with);
+}
+
#endif /* USE_ATOMICS_BUILTINS */
Modified: apr/apr/trunk/atomic/unix/ia32.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/atomic/unix/ia32.c?view=diff&rev=554995&r1=554994&r2=554995
==============================================================================
--- apr/apr/trunk/atomic/unix/ia32.c (original)
+++ apr/apr/trunk/atomic/unix/ia32.c Tue Jul 10 09:35:45 2007
@@ -108,4 +108,23 @@
return prev;
}
+APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with)
+{
+ void *prev;
+#if APR_SIZEOF_VOIDP == 4
+ asm volatile ("lock; xchgl %2, %1"
+ : "=a" (prev), "=m" (*mem)
+ : "r" (with), "m" (*mem)
+ : "memory");
+#elif APR_SIZEOF_VOIDP == 8
+ asm volatile ("lock; xchgq %q2, %1"
+ : "=a" (prev), "=m" (*mem)
+ : "r" ((unsigned long)with), "m" (*mem)
+ : "memory");
+#else
+#error APR_SIZEOF_VOIDP value not supported
+#endif
+ return prev;
+}
+
#endif /* USE_ATOMICS_IA32 */
Modified: apr/apr/trunk/atomic/unix/mutex.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/atomic/unix/mutex.c?view=diff&rev=554995&r1=554994&r2=554995
==============================================================================
--- apr/apr/trunk/atomic/unix/mutex.c (original)
+++ apr/apr/trunk/atomic/unix/mutex.c Tue Jul 10 09:35:45 2007
@@ -189,4 +189,17 @@
return prev;
}
+APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with)
+{
+ void *prev;
+ DECLARE_MUTEX_LOCKED(mutex, mem);
+
+ prev = *mem;
+ *mem = with;
+
+ MUTEX_UNLOCK(mutex);
+
+ return prev;
+}
+
#endif /* USE_ATOMICS_GENERIC */
Modified: apr/apr/trunk/atomic/unix/ppc.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/atomic/unix/ppc.c?view=diff&rev=554995&r1=554994&r2=554995
==============================================================================
--- apr/apr/trunk/atomic/unix/ppc.c (original)
+++ apr/apr/trunk/atomic/unix/ppc.c Tue Jul 10 09:35:45 2007
@@ -175,4 +175,35 @@
return prev;
}
+APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with)
+{
+ void *prev;
+#if APR_SIZEOF_VOIDP == 4
+ asm volatile (PPC_SYNC
+ "loop_%=:\n" /* lost reservation */
+ " lwarx %0,0,%1\n" /* load and reserve */
+ PPC405_ERR77_SYNC /* ppc405 Erratum 77 */
+ " stwcx. %2,0,%1\n" /* store new value */
+ " bne- loop_%=\n" /* loop if lost */
+ " isync\n" /* memory barrier */
+ : "=&r" (prev)
+ : "b" (mem), "r" (with)
+ : "cc", "memory");
+#elif APR_SIZEOF_VOIDP == 8
+ asm volatile (PPC_SYNC
+ "loop_%=:\n" /* lost reservation */
+ " ldarx %0,0,%1\n" /* load and reserve */
+ PPC405_ERR77_SYNC /* ppc405 Erratum 77 */
+ " stdcx. %2,0,%1\n" /* store new value */
+ " bne- loop_%=\n" /* loop if lost */
+ " isync\n" /* memory barrier */
+ : "=&r" (prev)
+ : "b" (mem), "r" (with)
+ : "cc", "memory");
+#else
+#error APR_SIZEOF_VOIDP value not supported
+#endif
+ return prev;
+}
+
#endif /* USE_ATOMICS_PPC */
Modified: apr/apr/trunk/atomic/unix/s390.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/atomic/unix/s390.c?view=diff&rev=554995&r1=554994&r2=554995
==============================================================================
--- apr/apr/trunk/atomic/unix/s390.c (original)
+++ apr/apr/trunk/atomic/unix/s390.c Tue Jul 10 09:35:45 2007
@@ -129,4 +129,27 @@
return prev;
}
+APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with)
+{
+ void *prev = (void *) *mem;
+#if APR_SIZEOF_VOIDP == 4
+ asm volatile ("loop_%=:\n"
+ " cs %0,%2,%1\n"
+ " jl loop_%=\n"
+ : "+d" (prev), "=Q" (*mem)
+ : "d" (with), "m" (*mem)
+ : "cc", "memory");
+#elif APR_SIZEOF_VOIDP == 8
+ asm volatile ("loop_%=:\n"
+ " csg %0,%2,%1\n"
+ " jl loop_%=\n"
+ : "+d" (prev), "=Q" (*mem)
+ : "d" (with), "m" (*mem)
+ : "cc", "memory");
+#else
+#error APR_SIZEOF_VOIDP value not supported
+#endif
+ return prev;
+}
+
#endif /* USE_ATOMICS_S390 */
Modified: apr/apr/trunk/atomic/unix/solaris.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/atomic/unix/solaris.c?view=diff&rev=554995&r1=554994&r2=554995
==============================================================================
--- apr/apr/trunk/atomic/unix/solaris.c (original)
+++ apr/apr/trunk/atomic/unix/solaris.c Tue Jul 10 09:35:45 2007
@@ -71,4 +71,9 @@
return atomic_cas_ptr(mem, cmp, with);
}
+APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with)
+{
+ return atomic_swap_ptr(mem, with);
+}
+
#endif /* USE_ATOMICS_SOLARIS */
Modified: apr/apr/trunk/atomic/win32/apr_atomic.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/atomic/win32/apr_atomic.c?view=diff&rev=554995&r1=554994&r2=554995
==============================================================================
--- apr/apr/trunk/atomic/win32/apr_atomic.c (original)
+++ apr/apr/trunk/atomic/win32/apr_atomic.c Tue Jul 10 09:35:45 2007
@@ -38,6 +38,9 @@
typedef WINBASEAPI void * (WINAPI * apr_atomic_win32_ptr_ptr_ptr_fn)
(volatile void **,
void *, const void *);
+typedef WINBASEAPI void * (WINAPI * apr_atomic_win32_ptr_ptr_fn)
+ (volatile void **,
+ void *);
APR_DECLARE(apr_uint32_t) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val)
{
@@ -133,5 +136,15 @@
return InterlockedExchange((long *)mem, val);
#else
return ((apr_atomic_win32_ptr_val_fn)InterlockedExchange)(mem, val);
+#endif
+}
+
+APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with)
+{
+#if (defined(_M_IA64) || defined(_M_AMD64) || defined(__MINGW32__)) && !defined(RC_INVOKED)
+ return InterlockedExchangePointer((void**)mem, with);
+#else
+ /* Too many VC6 users have stale win32 API files, stub this */
+ return ((apr_atomic_win32_ptr_ptr_fn)InterlockedExchangePointer)(mem, with);
#endif
}
Modified: apr/apr/trunk/include/apr_atomic.h
URL: http://svn.apache.org/viewvc/apr/apr/trunk/include/apr_atomic.h?view=diff&rev=554995&r1=554994&r2=554995
==============================================================================
--- apr/apr/trunk/include/apr_atomic.h (original)
+++ apr/apr/trunk/include/apr_atomic.h Tue Jul 10 09:35:45 2007
@@ -123,6 +123,14 @@
*/
APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, void *with, const void *cmp);
+/**
+ * exchange a pair of pointer values
+ * @param mem pointer to the pointer
+ * @param with what to swap it with
+ * @return the old value of the pointer
+ */
+APR_DECLARE(void*) apr_atomic_xchgptr(volatile void **mem, void *with);
+
/** @} */
#ifdef __cplusplus
Modified: apr/apr/trunk/test/testatomic.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/test/testatomic.c?view=diff&rev=554995&r1=554994&r2=554995
==============================================================================
--- apr/apr/trunk/test/testatomic.c (original)
+++ apr/apr/trunk/test/testatomic.c Tue Jul 10 09:35:45 2007
@@ -81,6 +81,17 @@
ABTS_INT_EQUAL(tc, 50, y32);
}
+static void test_xchgptr(abts_case *tc, void *data)
+{
+ int a;
+ volatile void *target_ptr = NULL;
+ void *old_ptr;
+
+ old_ptr = apr_atomic_xchgptr(&target_ptr, &a);
+ ABTS_PTR_EQUAL(tc, NULL, old_ptr);
+ ABTS_PTR_EQUAL(tc, &a, (void *) target_ptr);
+}
+
static void test_cas_equal(abts_case *tc, void *data)
{
apr_uint32_t casval = 0;
@@ -489,6 +500,7 @@
abts_run_test(suite, test_read32, NULL);
abts_run_test(suite, test_dec32, NULL);
abts_run_test(suite, test_xchg32, NULL);
+ abts_run_test(suite, test_xchgptr, NULL);
abts_run_test(suite, test_cas_equal, NULL);
abts_run_test(suite, test_cas_equal_nonnull, NULL);
abts_run_test(suite, test_cas_notequal, NULL);