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);