summaryrefslogtreecommitdiff
path: root/atomic
diff options
context:
space:
mode:
authorJeff Trawick <trawick@apache.org>2003-12-03 00:04:42 +0000
committerJeff Trawick <trawick@apache.org>2003-12-03 00:04:42 +0000
commita7498df3533310da3ac9cae1b16c2f66fc9345b4 (patch)
treed7b9c057bb11388c9f3d648fbac009a1f545bc30 /atomic
parentdaf3af5e27105ba65ddd27211d749139b462f6dd (diff)
downloadapr-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 'atomic')
-rw-r--r--atomic/netware/apr_atomic.c51
-rw-r--r--atomic/os390/atomic.c58
-rw-r--r--atomic/unix/apr_atomic.c195
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
+