diff options
author | trawick <trawick@13f79535-47bb-0310-9956-ffa450edef68> | 2003-12-03 00:04:42 +0000 |
---|---|---|
committer | trawick <trawick@13f79535-47bb-0310-9956-ffa450edef68> | 2003-12-03 00:04:42 +0000 |
commit | c4d1b096cb24b7517728e09c83e6002a24f74650 (patch) | |
tree | d7b9c057bb11388c9f3d648fbac009a1f545bc30 /atomic | |
parent | c49bf83561cc6651a961a2ab0939b6ddc0b3d172 (diff) | |
download | libapr-c4d1b096cb24b7517728e09c83e6002a24f74650.tar.gz |
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
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@64803 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'atomic')
-rw-r--r-- | atomic/netware/apr_atomic.c | 51 | ||||
-rw-r--r-- | atomic/os390/atomic.c | 58 | ||||
-rw-r--r-- | atomic/unix/apr_atomic.c | 195 |
3 files changed, 295 insertions, 9 deletions
diff --git a/atomic/netware/apr_atomic.c b/atomic/netware/apr_atomic.c index 243c0f576..9c8dfea1b 100644 --- a/atomic/netware/apr_atomic.c +++ b/atomic/netware/apr_atomic.c @@ -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); +} diff --git a/atomic/os390/atomic.c b/atomic/os390/atomic.c index 1c6d7db1b..088759352 100644 --- a/atomic/os390/atomic.c +++ b/atomic/os390/atomic.c @@ -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 @@ apr_uint32_t apr_atomic_cas32(volatile apr_atomic_t *mem, apr_uint32_t swap, 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; +} + diff --git a/atomic/unix/apr_atomic.c b/atomic/unix/apr_atomic.c index 34ef54275..b24dd72e2 100644 --- a/atomic/unix/apr_atomic.c +++ b/atomic/unix/apr_atomic.c @@ -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 @@ void *apr_atomic_casptr(volatile void **mem, void *with, const void *cmp) #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 + |