You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by tr...@apache.org on 2003/12/03 01:04:42 UTC
cvs commit: apr/test testatomic.c
trawick 2003/12/02 16:04:42
Modified: atomic/netware apr_atomic.c
atomic/os390 atomic.c
atomic/unix apr_atomic.c
include apr_atomic.h
include/arch/unix apr_arch_thread_mutex.h
test testatomic.c
Log:
move the implementations of apr atomics out of the public header file
in order to
. aid in keeping the different flavors consistent
. prevent bug fixes from requiring that apps be rebuilt
Reviewed and/or fixed by: Brad Nicholes, Greg Marr
Revision Changes Path
1.6 +48 -3 apr/atomic/netware/apr_atomic.c
Index: apr_atomic.c
===================================================================
RCS file: /home/cvs/apr/atomic/netware/apr_atomic.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- apr_atomic.c 1 Jan 2003 00:01:41 -0000 1.5
+++ apr_atomic.c 3 Dec 2003 00:04:42 -0000 1.6
@@ -52,13 +52,58 @@
* <http://www.apache.org/>.
*/
-
#include "apr.h"
#include "apr_atomic.h"
-int apr_atomic_dec(apr_atomic_t *mem)
+#include <stdlib.h>
+
+APR_DECLARE(apr_status_t) apr_atomic_init(apr_pool_t *pool)
+{
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(void) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val)
+{
+ atomic_add((unsigned long *)mem,(unsigned long)val);
+}
+
+APR_DECLARE(void) apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val)
+{
+ atomic_sub((unsigned long *)mem,(unsigned long)val);
+}
+
+APR_DECLARE(void) apr_atomic_inc32(volatile apr_uint32_t *mem)
+{
+ atomic_inc((unsigned long *)mem);
+}
+
+APR_DECLARE(void) apr_atomic_set32(volatile apr_uint32_t *mem, apr_uint32_t val)
{
- atomic_dec(mem);
+ *mem = val;
+}
+
+APR_DECLARE(apr_uint32_t) apr_atomic_read32(volatile apr_uint32_t *mem)
+{
+ return *mem;
+}
+
+APR_DECLARE(apr_uint32_t) apr_atomic_cas32(volatile apr_uint32_t *mem, apr_uint32_t with,apr_uint32_t cmp)
+{
+ return atomic_cmpxchg((unsigned long *)mem,(unsigned long)cmp,(unsigned long)with);
+}
+
+APR_DECLARE(apr_uint32_t) apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint32_t val)
+{
+ return atomic_xchg((unsigned long *)mem,(unsigned long)val);
+}
+
+APR_DECLARE(int) apr_atomic_dec32(volatile apr_uint32_t *mem)
+{
+ atomic_dec((unsigned long *)mem);
return *mem;
}
+APR_DECLARE(void *) apr_atomic_casptr(volatile void **mem, void *with, const void *cmp)
+{
+ return (void*)atomic_cmpxchg((unsigned long *)mem,(unsigned long)cmp,(unsigned long)with);
+}
1.6 +52 -6 apr/atomic/os390/atomic.c
Index: atomic.c
===================================================================
RCS file: /home/cvs/apr/atomic/os390/atomic.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- atomic.c 16 Nov 2003 01:33:02 -0000 1.5
+++ atomic.c 3 Dec 2003 00:04:42 -0000 1.6
@@ -56,21 +56,56 @@
#include "apr.h"
#include "apr_atomic.h"
-#if APR_HAS_THREADS
+#include <stdlib.h>
-apr_int32_t apr_atomic_add32(volatile apr_atomic_t *mem, apr_int32_t val)
+apr_status_t apr_atomic_init(apr_pool_t *p)
{
- apr_atomic_t old, new_val;
+ return APR_SUCCESS;
+}
+
+void apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val)
+{
+ apr_uint32_t old, new_val;
old = *mem; /* old is automatically updated on cs failure */
do {
new_val = old + val;
} while (__cs(&old, (cs_t *)mem, new_val));
+}
+
+void apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val)
+{
+ apr_atomic_add32(mem, -val);
+}
+
+void apr_atomic_inc32(volatile apr_uint32_t *mem)
+{
+ apr_atomic_add32(mem, 1);
+}
+
+int apr_atomic_dec32(volatile apr_uint32_t *mem)
+{
+ apr_uint32_t old, new_val;
+
+ old = *mem; /* old is automatically updated on cs failure */
+ do {
+ new_val = old - 1;
+ } while (__cs(&old, (cs_t *)mem, new_val));
+
+ return new_val != 0;
+}
+
+apr_uint32_t apr_atomic_read32(volatile apr_uint32_t *mem)
+{
+ return *mem;
+}
- return new_val;
+void apr_atomic_set32(volatile apr_uint32_t *mem, apr_uint32_t val)
+{
+ *mem = val;
}
-apr_uint32_t apr_atomic_cas32(volatile apr_atomic_t *mem, apr_uint32_t swap,
+apr_uint32_t apr_atomic_cas32(volatile apr_uint32_t *mem, apr_uint32_t swap,
apr_uint32_t cmp)
{
apr_uint32_t old = cmp;
@@ -79,4 +114,15 @@
return old; /* old is automatically updated from mem on cs failure */
}
-#endif /* APR_HAS_THREADS */
+apr_uint32_t apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint32_t val)
+{
+ apr_uint32_t old, new_val;
+
+ old = *mem; /* old is automatically updated on cs failure */
+ do {
+ new_val = val;
+ } while (__cs(&old, (cs_t *)mem, new_val));
+
+ return old;
+}
+
1.26 +195 -0 apr/atomic/unix/apr_atomic.c
Index: apr_atomic.c
===================================================================
RCS file: /home/cvs/apr/atomic/unix/apr_atomic.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- apr_atomic.c 16 Nov 2003 01:33:02 -0000 1.25
+++ apr_atomic.c 3 Dec 2003 00:04:42 -0000 1.26
@@ -56,6 +56,193 @@
#include "apr_atomic.h"
#include "apr_thread_mutex.h"
+#if defined(WIN32)
+
+#define apr_atomic_t LONG /* not used */
+
+APR_DECLARE(apr_status_t) apr_atomic_init(apr_pool_t *p)
+{
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(void *) apr_atomic_casptr(volatile void **mem, void *with, const void *cmp)
+{
+ return InterlockedCompareExchangePointer(mem, with, cmp);
+}
+
+/*
+ * Remapping function pointer type to accept apr_uint32_t's type-safely
+ * as the arguments for as our apr_atomic_foo32 Functions
+ */
+typedef WINBASEAPI apr_uint32_t (WINAPI * apr_atomic_win32_ptr_fn)
+ (apr_uint32_t volatile *);
+typedef WINBASEAPI apr_uint32_t (WINAPI * apr_atomic_win32_ptr_val_fn)
+ (apr_uint32_t volatile *,
+ apr_uint32_t);
+typedef WINBASEAPI apr_uint32_t (WINAPI * apr_atomic_win32_ptr_val_val_fn)
+ (apr_uint32_t volatile *,
+ apr_uint32_t, apr_uint32_t);
+
+APR_DECLARE(void) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val)
+{
+ ((apr_atomic_win32_ptr_val_fn)InterlockedExchangeAdd)(mem, val);
+}
+#define APR_OVERRIDE_ATOMIC_ADD32
+
+APR_DECLARE(void) apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val)
+{
+ ((apr_atomic_win32_ptr_val_fn)InterlockedExchangeAdd)(mem, -val);
+}
+#define APR_OVERRIDE_ATOMIC_SUB32
+
+APR_DECLARE(void) apr_atomic_inc32(volatile apr_uint32_t *mem)
+{
+ ((apr_atomic_win32_ptr_fn)InterlockedIncrement)(mem);
+}
+#define APR_OVERRIDE_ATOMIC_INC32
+
+APR_DECLARE(int) apr_atomic_dec32(volatile apr_uint32_t *mem)
+{
+ return ((apr_atomic_win32_ptr_fn)InterlockedDecrement)(mem);
+}
+#define APR_OVERRIDE_ATOMIC_DEC32
+
+APR_DECLARE(void) apr_atomic_set32(volatile apr_uint32_t *mem, apr_uint32_t val)
+{
+ ((apr_atomic_win32_ptr_val_fn)InterlockedExchange)(mem, val);
+}
+#define APR_OVERRIDE_ATOMIC_SET32
+
+APR_DECLARE(apr_uint32_t) apr_atomic_cas32(volatile apr_uint32_t *mem, apr_uint32_t with,
+ apr_uint32_t cmp)
+{
+ return ((apr_atomic_win32_ptr_val_val_fn)InterlockedCompareExchange)(mem, with, cmp);
+}
+#define APR_OVERRIDE_ATOMIC_CAS32
+
+APR_DECLARE(apr_uint32_t) apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint32_t val)
+{
+ return ((apr_atomic_win32_ptr_val_fn)InterlockedExchange)(mem, val);
+}
+#define APR_OVERRIDE_ATOMIC_XCHG32
+
+#endif /* WIN32 */
+
+#if defined(__FreeBSD__) && !defined(__i386__) && !APR_FORCE_ATOMIC_GENERIC
+
+#include <machine/atomic.h>
+
+#define apr_atomic_t apr_uint32_t /* unused */
+
+APR_DECLARE(void) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val)
+{
+ atomic_add_int(mem, val);
+}
+#define APR_OVERRIDE_ATOMIC_ADD32
+
+APR_DECLARE(int) apr_atomic_dec32(volatile apr_uint32_t *mem)
+{
+ return atomic_subtract_int(mem, 1);
+}
+#define APR_OVERRIDE_ATOMIC_DEC32
+
+APR_DECLARE(void) apr_atomic_inc32(volatile apr_uint32_t *mem)
+{
+ atomic_add_int(mem, 1);
+}
+#define APR_OVERRIDE_ATOMIC_INC32
+
+APR_DECLARE(void) apr_atomic_set32(volatile apr_uint32_t *mem, apr_uint32_t val)
+{
+ atomic_set_int(mem, val);
+}
+#define APR_OVERRIDE_ATOMIC_SET32
+
+#endif /* __FreeBSD__ && !__i386__ */
+
+#if (defined(__linux__) || defined(__EMX__) || defined(__FreeBSD__)) \
+ && defined(__i386__) && !APR_FORCE_ATOMIC_GENERIC
+
+/* #define apr_atomic_t apr_uint32_t UNUSED */
+
+APR_DECLARE(apr_uint32_t) apr_atomic_cas32(volatile apr_uint32_t *mem,
+ apr_uint32_t with,
+ apr_uint32_t cmp)
+{
+ apr_uint32_t prev;
+
+ asm volatile ("lock; cmpxchgl %1, %2"
+ : "=a" (prev)
+ : "r" (with), "m" (*(mem)), "0"(cmp)
+ : "memory");
+ return prev;
+}
+#define APR_OVERRIDE_ATOMIC_CAS32
+
+APR_DECLARE(void) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val)
+{
+ asm volatile ("lock; addl %1, %0"
+ :
+ : "m" (*(mem)), "r" (val)
+ : "memory");
+}
+#define APR_OVERRIDE_ATOMIC_ADD32
+
+APR_DECLARE(void) apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val)
+{
+ asm volatile ("lock; subl %1, %0"
+ :
+ : "m" (*(mem)), "r" (val)
+ : "memory");
+}
+#define APR_OVERRIDE_ATOMIC_SUB32
+
+APR_DECLARE(int) apr_atomic_dec32(volatile apr_uint32_t *mem)
+{
+ int prev;
+
+ asm volatile ("mov $0, %%eax;\n\t"
+ "lock; decl %1;\n\t"
+ "setnz %%al;\n\t"
+ "mov %%eax, %0"
+ : "=r" (prev)
+ : "m" (*(mem))
+ : "memory", "%eax");
+ return prev;
+}
+#define APR_OVERRIDE_ATOMIC_DEC32
+
+APR_DECLARE(void) apr_atomic_inc32(volatile apr_uint32_t *mem)
+{
+ asm volatile ("lock; incl %0"
+ :
+ : "m" (*(mem))
+ : "memory");
+}
+#define APR_OVERRIDE_ATOMIC_INC32
+
+APR_DECLARE(void) apr_atomic_set32(volatile apr_uint32_t *mem, apr_uint32_t val)
+{
+ *mem = val;
+}
+#define APR_OVERRIDE_ATOMIC_SET32
+
+APR_DECLARE(apr_uint32_t) apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint32_t val)
+{
+ apr_uint32_t prev = val;
+
+ asm volatile ("lock; xchgl %0, %1"
+ : "=r" (prev)
+ : "m" (*(mem)), "0"(prev)
+ : "memory");
+ return prev;
+}
+#define APR_OVERRIDE_ATOMIC_XCHG32
+
+/*#define apr_atomic_init(pool) APR_SUCCESS*/
+
+#endif /* (__linux__ || __EMX__ || __FreeBSD__) && __i386__ */
+
#if !defined(apr_atomic_init) && !defined(APR_OVERRIDE_ATOMIC_INIT)
#if APR_HAS_THREADS
@@ -242,3 +429,11 @@
#endif /* APR_HAS_THREADS */
}
#endif /*!defined(apr_atomic_casptr) && !defined(APR_OVERRIDE_ATOMIC_CASPTR) */
+
+#if !defined(APR_OVERRIDE_ATOMIC_READ32)
+APR_DECLARE(apr_uint32_t) apr_atomic_read32(volatile apr_uint32_t *mem)
+{
+ return *mem;
+}
+#endif
+
1.65 +10 -287 apr/include/apr_atomic.h
Index: apr_atomic.h
===================================================================
RCS file: /home/cvs/apr/include/apr_atomic.h,v
retrieving revision 1.64
retrieving revision 1.65
diff -u -r1.64 -r1.65
--- apr_atomic.h 16 Nov 2003 20:09:45 -0000 1.64
+++ apr_atomic.h 3 Dec 2003 00:04:42 -0000 1.65
@@ -67,13 +67,6 @@
#include "apr.h"
#include "apr_pools.h"
-/* Platform includes for atomics */
-#if defined(NETWARE) || defined(__MVS__) /* OS/390 */
-#include <stdlib.h>
-#elif defined(__FreeBSD__) && !defined(__i386__)
-#include <machine/atomic.h>
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -84,21 +77,13 @@
* @{
*/
-/* easiest way to get these documented for the moment */
-#if defined(DOXYGEN)
-/**
- * structure for holding a atomic value.
- * this number >only< has a 24 bit size on some platforms
- */
-typedef apr_atomic_t;
-
/**
* this function is required on some platforms to initialize the
* atomic operation's internal structures
* @param p pool
* @return APR_SUCCESS on successful completion
*/
-apr_status_t apr_atomic_init(apr_pool_t *p);
+APR_DECLARE(apr_status_t) apr_atomic_init(apr_pool_t *p);
/*
* Atomic operations on 32-bit values
@@ -110,40 +95,40 @@
* atomically read an apr_uint32_t from memory
* @param mem the pointer
*/
-apr_uint32_t apr_atomic_read32(volatile apr_uint32_t *mem);
+APR_DECLARE(apr_uint32_t) apr_atomic_read32(volatile apr_uint32_t *mem);
/**
* atomically set an apr_uint32_t in memory
* @param mem pointer to the object
*/
-void apr_atomic_set32(volatile apr_uint32_t *mem, apr_uint32_t val);
+APR_DECLARE(void) apr_atomic_set32(volatile apr_uint32_t *mem, apr_uint32_t val);
/**
* atomically add 'val' to an apr_uint32_t
* @param mem pointer to the object
* @param val amount to add
*/
-void apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val);
+APR_DECLARE(void) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val);
/**
* atomically subtract 'val' from an apr_uint32_t
* @param mem pointer to the object
* @param val amount to subtract
*/
-void apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val);
+APR_DECLARE(void) apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val);
/**
* atomically increment an apr_uint32_t by 1
* @param mem pointer to the object
*/
-void apr_atomic_inc32(volatile apr_uint32_t *mem);
+APR_DECLARE(void) apr_atomic_inc32(volatile apr_uint32_t *mem);
/**
* atomically decrement an apr_uint32_t by 1
* @param mem pointer to the atomic value
* @return zero if the value becomes zero on decrement, otherwise non-zero
*/
-int apr_atomic_dec32(volatile apr_uint32_t *mem);
+APR_DECLARE(int) apr_atomic_dec32(volatile apr_uint32_t *mem);
/**
* compare an apr_uint32_t's value with 'cmp'.
@@ -153,7 +138,7 @@
* @param cmp the value to compare it to
* @return the old value of *mem
*/
-apr_uint32_t apr_atomic_cas32(volatile apr_uint32_t *mem, apr_uint32_t with,
+APR_DECLARE(apr_uint32_t) apr_atomic_cas32(volatile apr_uint32_t *mem, apr_uint32_t with,
apr_uint32_t cmp);
/**
@@ -162,7 +147,7 @@
* @param val what to swap it with
* @return the old value of *mem
*/
-apr_uint32_t apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint32_t val);
+APR_DECLARE(apr_uint32_t) apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint32_t val);
/**
* compare the pointer's value with cmp.
@@ -172,269 +157,7 @@
* @param cmp the value to compare it to
* @return the old value of the pointer
*/
-void *apr_atomic_casptr(volatile void **mem, void *with, const void *cmp);
-#else /* !DOXYGEN */
-
-/* The following definitions provide optimized, OS-specific
- * implementations of the APR atomic functions on various
- * platforms. Any atomic operation that isn't redefined as
- * a macro here will be declared as a function later, and
- * apr_atomic.c will provide a mutex-based default implementation.
- */
-
-#if defined(WIN32)
-
-#define apr_atomic_t LONG
-
-#define apr_atomic_init(pool) APR_SUCCESS
-#define apr_atomic_casptr(mem,with,cmp) InterlockedCompareExchangePointer(mem,with,cmp)
-
-/*
- * Remapping function pointer type to accept apr_uint32_t's type-safely
- * as the arguments for as our apr_atomic_foo32 Functions
- */
-typedef WINBASEAPI apr_uint32_t (WINAPI * apr_atomic_win32_ptr_fn)
- (apr_uint32_t volatile *);
-typedef WINBASEAPI apr_uint32_t (WINAPI * apr_atomic_win32_ptr_val_fn)
- (apr_uint32_t volatile *,
- apr_uint32_t);
-typedef WINBASEAPI apr_uint32_t (WINAPI * apr_atomic_win32_ptr_val_val_fn)
- (apr_uint32_t volatile *,
- apr_uint32_t, apr_uint32_t);
-
-#define apr_atomic_add32(mem, val) \
- ((apr_atomic_win32_ptr_val_fn)InterlockedExchangeAdd)(mem,val)
-#define apr_atomic_sub32(mem, val) \
- ((apr_atomic_win32_ptr_val_fn)InterlockedExchangeAdd)(mem,-(val))
-#define apr_atomic_inc32(mem) \
- ((apr_atomic_win32_ptr_fn)InterlockedIncrement)(mem)
-#define apr_atomic_dec32(mem) \
- ((apr_atomic_win32_ptr_fn)InterlockedDecrement)(mem)
-#define apr_atomic_set32(mem, val) \
- ((apr_atomic_win32_ptr_val_fn)InterlockedExchange)(mem,val)
-#define apr_atomic_read32(mem) (*(mem))
-#define apr_atomic_cas32(mem,with,cmp) \
- ((apr_atomic_win32_ptr_val_val_fn)InterlockedCompareExchange)(mem,with,cmp)
-#define apr_atomic_xchg32(mem,val) \
- ((apr_atomic_win32_ptr_val_fn)InterlockedExchange)(mem,val)
-
-#elif defined(NETWARE)
-
-#define apr_atomic_init(pool) APR_SUCCESS
-#define apr_atomic_add32(mem, val) atomic_add((unsigned long *)(mem),(unsigned long)(val))
-#define apr_atomic_sub32(mem, val) atomic_sub((unsigned long *)(mem),(unsigned long)(val))
-#define apr_atomic_inc32(mem) atomic_inc((unsigned long *)(mem))
-#define apr_atomic_set32(mem, val) (*mem = val)
-#define apr_atomic_read32(mem) (*mem)
-#define apr_atomic_cas32(mem,with,cmp) atomic_cmpxchg((unsigned long *)(mem),(unsigned long)(cmp),(unsigned long)(with))
-#define apr_atomic_xchg32(mem, val) atomic_xchg((unsigned long *)(mem),(unsigned long)val)
-
-int apr_atomic_dec32(apr_uint32_t *mem);
-void *apr_atomic_casptr(void **mem, void *with, const void *cmp);
-
-#define APR_OVERRIDE_ATOMIC_READ32 1
-#define APR_OVERRIDE_ATOMIC_SET32 1
-#define APR_OVERRIDE_ATOMIC_ADD32 1
-#define APR_OVERRIDE_ATOMIC_SUB32 1
-#define APR_OVERRIDE_ATOMIC_INC32 1
-#define APR_OVERRIDE_ATOMIC_DEC32 1
-#define APR_OVERRIDE_ATOMIC_CAS32 1
-#define APR_OVERRIDE_ATOMIC_XCHG32 1
-
-#define APR_OVERRIDE_ATOMIC_CASPTR 1
-
-inline int apr_atomic_dec32(apr_uint32_t *mem)
-{
- atomic_dec((unsigned long *)mem);
- return *mem;
-}
-
-inline void *apr_atomic_casptr(void **mem, void *with, const void *cmp)
-{
- return (void*)atomic_cmpxchg((unsigned long *)mem,(unsigned long)cmp,(unsigned long)with);
-}
-
-#define APR_OVERRIDE_ATOMIC_READ 1
-#define APR_OVERRIDE_ATOMIC_SET 1
-#define APR_OVERRIDE_ATOMIC_ADD 1
-#define APR_OVERRIDE_ATOMIC_INC 1
-#define APR_OVERRIDE_ATOMIC_DEC 1
-#define APR_OVERRIDE_ATOMIC_CAS 1
-
-#elif defined(__FreeBSD__) && !defined(__i386__)
-
-#define apr_atomic_t apr_uint32_t
-#define apr_atomic_add32(mem, val) atomic_add_int(mem,val)
-#define apr_atomic_dec32(mem) atomic_subtract_int(mem,1)
-#define apr_atomic_inc32(mem) atomic_add_int(mem,1)
-#define apr_atomic_set32(mem, val) atomic_set_int(mem, val)
-#define apr_atomic_read32(mem) (*mem)
-
-#elif (defined(__linux__) || defined(__EMX__) || defined(__FreeBSD__)) \
- && defined(__i386__) && !APR_FORCE_ATOMIC_GENERIC
-
-#define apr_atomic_t apr_uint32_t
-#define apr_atomic_cas32(mem,with,cmp) \
-({ apr_atomic_t prev; \
- asm volatile ("lock; cmpxchgl %1, %2" \
- : "=a" (prev) \
- : "r" (with), "m" (*(mem)), "0"(cmp) \
- : "memory"); \
- prev;})
-
-#define apr_atomic_add32(mem, val) \
- asm volatile ("lock; addl %1, %0" \
- : \
- : "m" (*(mem)), "r" (val) \
- : "memory")
-
-#define apr_atomic_sub32(mem, val) \
- asm volatile ("lock; subl %1, %0" \
- : \
- : "m" (*(mem)), "r" (val) \
- : "memory")
-
-#define apr_atomic_dec32(mem) \
-({ int prev; \
- asm volatile ("mov $0, %%eax;\n\t" \
- "lock; decl %1;\n\t" \
- "setnz %%al;\n\t" \
- "mov %%eax, %0" \
- : "=r" (prev) \
- : "m" (*(mem)) \
- : "memory", "%eax"); \
- prev;})
-
-#define apr_atomic_inc32(mem) \
- asm volatile ("lock; incl %0" \
- : \
- : "m" (*(mem)) \
- : "memory")
-
-#define apr_atomic_set32(mem, val) (*(mem) = val)
-#define apr_atomic_read32(mem) (*(mem))
-
-#define apr_atomic_xchg32(mem,val) \
-({ apr_uint32_t prev = val; \
- asm volatile ("lock; xchgl %0, %1" \
- : "=r" (prev) \
- : "m" (*(mem)), "0"(prev) \
- : "memory"); \
- prev;})
-
-/*#define apr_atomic_init(pool) APR_SUCCESS*/
-
-#elif defined(__MVS__) /* OS/390 */
-
-#define apr_atomic_t cs_t
-
-apr_int32_t apr_atomic_add32(volatile apr_atomic_t *mem, apr_int32_t val);
-apr_uint32_t apr_atomic_cas32(volatile apr_atomic_t *mem, apr_uint32_t swap,
- apr_uint32_t cmp);
-#define APR_OVERRIDE_ATOMIC_ADD 1
-#define APR_OVERRIDE_ATOMIC_CAS 1
-
-#define apr_atomic_inc32(mem) apr_atomic_add32(mem, 1)
-#define apr_atomic_dec32(mem) apr_atomic_add32(mem, -1)
-/*#define apr_atomic_init(pool) APR_SUCCESS*/
-
-/* warning: the following two operations, _read and _set, are atomic
- * if the memory variables are aligned (the usual case).
- *
- * If you try really hard and manage to mis-align them, they are not
- * guaranteed to be atomic on S/390. But then your program will blow up
- * with SIGBUS on a sparc, or with a S0C6 abend if you use the mis-aligned
- * variables with other apr_atomic_* operations on OS/390.
- */
-
-#define apr_atomic_read32(p) (*p)
-#define apr_atomic_set32(mem, val) (*mem = val)
-
-#endif /* end big if-elseif switch for platform-specifics */
-
-
-/* Default implementation of the atomic API
- * The definitions above may override some or all of the
- * atomic functions with optimized, platform-specific versions.
- * Any operation that hasn't been overridden as a macro above
- * is declared as a function here, unless APR_OVERRIDE_ATOMIC_[OPERATION]
- * is defined. (The purpose of the APR_OVERRIDE_ATOMIC_* is
- * to allow a platform to declare an apr_atomic_*() function
- * with a different signature than the default.)
- */
-
-#if !defined(apr_atomic_t)
-#define apr_atomic_t apr_uint32_t
-#endif
-
-#if !defined(apr_atomic_init) && !defined(APR_OVERRIDE_ATOMIC_INIT)
-apr_status_t apr_atomic_init(apr_pool_t *p);
-#endif
-
-#if !defined(apr_atomic_read32) && !defined(APR_OVERRIDE_ATOMIC_READ32)
-#define apr_atomic_read32(p) *p
-#endif
-
-#if !defined(apr_atomic_set32) && !defined(APR_OVERRIDE_ATOMIC_SET32)
-void apr_atomic_set32(volatile apr_uint32_t *mem, apr_uint32_t val);
-#define APR_ATOMIC_NEED_DEFAULT_INIT 1
-#endif
-
-#if !defined(apr_atomic_add32) && !defined(APR_OVERRIDE_ATOMIC_ADD32)
-void apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val);
-#define APR_ATOMIC_NEED_DEFAULT_INIT 1
-#endif
-
-#if !defined(apr_atomic_sub32) && !defined(APR_OVERRIDE_ATOMIC_SUB32)
-void apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val);
-#define APR_ATOMIC_NEED_DEFAULT_INIT 1
-#endif
-
-#if !defined(apr_atomic_inc32) && !defined(APR_OVERRIDE_ATOMIC_INC32)
-void apr_atomic_inc32(volatile apr_uint32_t *mem);
-#define APR_ATOMIC_NEED_DEFAULT_INIT 1
-#endif
-
-#if !defined(apr_atomic_dec32) && !defined(APR_OVERRIDE_ATOMIC_DEC32)
-int apr_atomic_dec32(volatile apr_uint32_t *mem);
-#define APR_ATOMIC_NEED_DEFAULT_INIT 1
-#endif
-
-#if !defined(apr_atomic_cas32) && !defined(APR_OVERRIDE_ATOMIC_CAS32)
-apr_uint32_t apr_atomic_cas32(volatile apr_uint32_t *mem, apr_uint32_t with,
- apr_uint32_t cmp);
-#define APR_ATOMIC_NEED_DEFAULT_INIT 1
-#endif
-
-#if !defined(apr_atomic_xchg32) && !defined(APR_OVERRIDE_ATOMIC_XCHG32)
-apr_uint32_t apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint32_t val);
-#define APR_ATOMIC_NEED_DEFAULT_INIT 1
-#endif
-
-#if !defined(apr_atomic_casptr) && !defined(APR_OVERRIDE_ATOMIC_CASPTR)
-#if APR_SIZEOF_VOIDP == 4
-#define apr_atomic_casptr(mem, with, cmp) (void *)apr_atomic_cas32((apr_uint32_t *)(mem), (long)(with), (long)cmp)
-#else
-void *apr_atomic_casptr(volatile void **mem, void *with, const void *cmp);
-#define APR_ATOMIC_NEED_DEFAULT_INIT 1
-#endif
-#endif
-
-#ifndef APR_ATOMIC_NEED_DEFAULT_INIT
-#define APR_ATOMIC_NEED_DEFAULT_INIT 0
-#endif
-
-/* If we're using the default versions of any of the atomic functions,
- * we'll need the atomic init to set up mutexes. If a platform-specific
- * override above has replaced the atomic_init with a macro, it's an error.
- */
-#if APR_ATOMIC_NEED_DEFAULT_INIT
-#if defined(apr_atomic_init) || defined(APR_OVERRIDE_ATOMIC_INIT)
-#error Platform has redefined apr_atomic_init, but other default atomics require a default apr_atomic_init
-#endif
-#endif /* APR_ATOMIC_NEED_DEFAULT_INIT */
-
-#endif /* !DOXYGEN */
+APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, void *with, const void *cmp);
/** @} */
1.3 +1 -1 apr/include/arch/unix/apr_arch_thread_mutex.h
Index: apr_arch_thread_mutex.h
===================================================================
RCS file: /home/cvs/apr/include/arch/unix/apr_arch_thread_mutex.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- apr_arch_thread_mutex.h 7 Aug 2003 22:16:24 -0000 1.2
+++ apr_arch_thread_mutex.h 3 Dec 2003 00:04:42 -0000 1.3
@@ -71,7 +71,7 @@
apr_pool_t *pool;
pthread_mutex_t mutex;
volatile apr_os_thread_t owner;
- volatile apr_atomic_t owner_ref;
+ volatile apr_uint32_t owner_ref;
char nested; /* a boolean */
};
#endif
1.35 +2 -2 apr/test/testatomic.c
Index: testatomic.c
===================================================================
RCS file: /home/cvs/apr/test/testatomic.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- testatomic.c 16 Nov 2003 23:58:48 -0000 1.34
+++ testatomic.c 3 Dec 2003 00:04:42 -0000 1.35
@@ -74,7 +74,7 @@
#endif
apr_pool_t *context;
-apr_atomic_t y; /* atomic locks */
+apr_uint32_t y; /* atomic locks */
apr_uint32_t y32;
static apr_status_t check_basic_atomics32(void)
@@ -199,7 +199,7 @@
int value = 0;
apr_status_t exit_ret_val = 123; /* just some made up number to check on later */
-#define NUM_THREADS 50
+#define NUM_THREADS 20
#define NUM_ITERATIONS 200000
void * APR_THREAD_FUNC thread_func_mutex(apr_thread_t *thd, void *data)
{