diff options
author | Jeff Trawick <trawick@apache.org> | 2003-12-03 00:04:42 +0000 |
---|---|---|
committer | Jeff Trawick <trawick@apache.org> | 2003-12-03 00:04:42 +0000 |
commit | a7498df3533310da3ac9cae1b16c2f66fc9345b4 (patch) | |
tree | d7b9c057bb11388c9f3d648fbac009a1f545bc30 /include/apr_atomic.h | |
parent | daf3af5e27105ba65ddd27211d749139b462f6dd (diff) | |
download | apr-a7498df3533310da3ac9cae1b16c2f66fc9345b4.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: https://svn.apache.org/repos/asf/apr/apr/trunk@64803 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'include/apr_atomic.h')
-rw-r--r-- | include/apr_atomic.h | 297 |
1 files changed, 10 insertions, 287 deletions
diff --git a/include/apr_atomic.h b/include/apr_atomic.h index 14f39c996..3750429cf 100644 --- a/include/apr_atomic.h +++ b/include/apr_atomic.h @@ -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 @@ extern "C" { * @{ */ -/* 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 @@ apr_status_t apr_atomic_init(apr_pool_t *p); * 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 @@ int apr_atomic_dec32(volatile apr_uint32_t *mem); * @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 @@ apr_uint32_t apr_atomic_cas32(volatile apr_uint32_t *mem, apr_uint32_t with, * @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 @@ apr_uint32_t apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint32_t val); * @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); /** @} */ |