summaryrefslogtreecommitdiff
path: root/atomic
diff options
context:
space:
mode:
authorDavi Arnaut <davi@apache.org>2007-07-10 16:35:45 +0000
committerDavi Arnaut <davi@apache.org>2007-07-10 16:35:45 +0000
commit99f54f536886d68d1d6b13dad297b8fb7741232c (patch)
treebda6af4a9c2930481adffbb7fcbeb8a3e4c11eb7 /atomic
parenteb6350350b65c10903b2dc13a6b92cf3aa4ce5c0 (diff)
downloadapr-99f54f536886d68d1d6b13dad297b8fb7741232c.tar.gz
Introduce apr_atomic_xchgptr, which atomically exchanges a pair of pointer
values. Missing OS/390 implementation. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@554995 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'atomic')
-rw-r--r--atomic/netware/apr_atomic.c5
-rw-r--r--atomic/unix/builtins.c7
-rw-r--r--atomic/unix/ia32.c19
-rw-r--r--atomic/unix/mutex.c13
-rw-r--r--atomic/unix/ppc.c31
-rw-r--r--atomic/unix/s390.c23
-rw-r--r--atomic/unix/solaris.c5
-rw-r--r--atomic/win32/apr_atomic.c13
8 files changed, 116 insertions, 0 deletions
diff --git a/atomic/netware/apr_atomic.c b/atomic/netware/apr_atomic.c
index 94a354977..b5d965b09 100644
--- a/atomic/netware/apr_atomic.c
+++ b/atomic/netware/apr_atomic.c
@@ -68,3 +68,8 @@ APR_DECLARE(void *) apr_atomic_casptr(volatile void **mem, void *with, const voi
{
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);
+}
diff --git a/atomic/unix/builtins.c b/atomic/unix/builtins.c
index 274599614..745acf155 100644
--- a/atomic/unix/builtins.c
+++ b/atomic/unix/builtins.c
@@ -71,4 +71,11 @@ APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, void *with, const void
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 */
diff --git a/atomic/unix/ia32.c b/atomic/unix/ia32.c
index bcf9d5661..191298c4a 100644
--- a/atomic/unix/ia32.c
+++ b/atomic/unix/ia32.c
@@ -108,4 +108,23 @@ APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, void *with, const void
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 */
diff --git a/atomic/unix/mutex.c b/atomic/unix/mutex.c
index 17b605fcd..cb23ede34 100644
--- a/atomic/unix/mutex.c
+++ b/atomic/unix/mutex.c
@@ -189,4 +189,17 @@ APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, void *with, const void
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 */
diff --git a/atomic/unix/ppc.c b/atomic/unix/ppc.c
index 149347eae..d7673d5ee 100644
--- a/atomic/unix/ppc.c
+++ b/atomic/unix/ppc.c
@@ -175,4 +175,35 @@ APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, void *with, const void
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 */
diff --git a/atomic/unix/s390.c b/atomic/unix/s390.c
index a81ffdd16..3e2332077 100644
--- a/atomic/unix/s390.c
+++ b/atomic/unix/s390.c
@@ -129,4 +129,27 @@ APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, void *with, const void
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 */
diff --git a/atomic/unix/solaris.c b/atomic/unix/solaris.c
index f74a7ef2d..ba544522f 100644
--- a/atomic/unix/solaris.c
+++ b/atomic/unix/solaris.c
@@ -71,4 +71,9 @@ APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, void *with, const void
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 */
diff --git a/atomic/win32/apr_atomic.c b/atomic/win32/apr_atomic.c
index e88f2e256..44e8ca2dd 100644
--- a/atomic/win32/apr_atomic.c
+++ b/atomic/win32/apr_atomic.c
@@ -38,6 +38,9 @@ typedef WINBASEAPI apr_uint32_t (WINAPI * apr_atomic_win32_ptr_val_val_fn)
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)
{
@@ -135,3 +138,13 @@ APR_DECLARE(apr_uint32_t) apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint
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
+}