move whether atomic byte/short exists to uatomic_arch_*.h
authorPaolo Bonzini <pbonzini@redhat.com>
Mon, 1 Mar 2010 19:00:22 +0000 (14:00 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Mon, 1 Mar 2010 19:00:22 +0000 (14:00 -0500)
And add more generic implementations to uatomic_defaults.h.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
tests/test_uatomic.c
urcu/uatomic_arch_x86.h
urcu/uatomic_generic.h

index c0f36fe5f90f5e346be54befc1f93b09b2050b50..5682655c47df257e0852caf86d146b6b090ecb01 100644 (file)
@@ -1,21 +1,10 @@
 #include <stdio.h>
 #include <assert.h>
-
-#define UATOMIC_NO_LINK_ERROR
 #include <urcu/uatomic_arch.h>
 
-#if (defined(__i386__) || defined(__x86_64__))
-#define HAS_ATOMIC_BYTE
-#define HAS_ATOMIC_SHORT
-#endif
-
 struct testvals {
-#ifdef HAS_ATOMIC_BYTE
        unsigned char c;
-#endif
-#ifdef HAS_ATOMIC_SHORT
        unsigned short s;
-#endif
        unsigned int i;
        unsigned long l;
 };
@@ -54,10 +43,10 @@ do {                                                \
 
 int main(int argc, char **argv)
 {
-#ifdef HAS_ATOMIC_BYTE
+#ifdef UATOMIC_HAS_ATOMIC_BYTE
        do_test(&vals.c);
 #endif
-#ifdef HAS_ATOMIC_SHORT
+#ifdef UATOMIC_HAS_ATOMIC_SHORT
        do_test(&vals.s);
 #endif
        do_test(&vals.i);
index e358be3673552dd9919ca6579e2c83071410157a..666e498f326c4c3b8ce025352b3f385416dbc32b 100644 (file)
@@ -23,6 +23,9 @@
 #include <urcu/compiler.h>
 #include <urcu/system.h>
 
+#define UATOMIC_HAS_ATOMIC_BYTE
+#define UATOMIC_HAS_ATOMIC_SHORT
+
 #ifdef __cplusplus
 extern "C" {
 #endif 
index 6e2c23e3841b9bbf4f0ba3b6d20e0ea3be0ad8cc..9ee7b7bdc22a6bedeef45ef6447d930162375c99 100644 (file)
@@ -65,6 +65,14 @@ unsigned long _uatomic_cmpxchg(void *addr, unsigned long old,
                              unsigned long _new, int len)
 {
        switch (len) {
+#ifdef UATOMIC_HAS_ATOMIC_BYTE
+       case 1:
+               return __sync_val_compare_and_swap_1(addr, old, _new);
+#endif
+#ifdef UATOMIC_HAS_ATOMIC_SHORT
+       case 2:
+               return __sync_val_compare_and_swap_2(addr, old, _new);
+#endif
        case 4:
                return __sync_val_compare_and_swap_4(addr, old, _new);
 #if (BITS_PER_LONG == 64)
@@ -91,6 +99,14 @@ unsigned long _uatomic_add_return(void *addr, unsigned long val,
                                 int len)
 {
        switch (len) {
+#ifdef UATOMIC_HAS_ATOMIC_BYTE
+       case 1:
+               return __sync_add_and_fetch_1(addr, val);
+#endif
+#ifdef UATOMIC_HAS_ATOMIC_SHORT
+       case 2:
+               return __sync_add_and_fetch_2(addr, val);
+#endif
        case 4:
                return __sync_add_and_fetch_4(addr, val);
 #if (BITS_PER_LONG == 64)
@@ -116,6 +132,30 @@ static inline __attribute__((always_inline))
 unsigned long _uatomic_exchange(void *addr, unsigned long val, int len)
 {
        switch (len) {
+#ifdef UATOMIC_HAS_ATOMIC_BYTE
+       case 1:
+       {
+               unsigned char old;
+
+               do {
+                       old = uatomic_read((unsigned char *)addr);
+               } while (!__sync_bool_compare_and_swap_1(addr, old, val));
+
+               return old;
+       }
+#endif
+#ifdef UATOMIC_HAS_ATOMIC_SHORT
+       case 2:
+       {
+               unsigned short old;
+
+               do {
+                       old = uatomic_read((unsigned short *)addr);
+               } while (!__sync_bool_compare_and_swap_2(addr, old, val));
+
+               return old;
+       }
+#endif
        case 4:
        {
                unsigned int old;
@@ -157,6 +197,34 @@ static inline __attribute__((always_inline))
 unsigned long _uatomic_add_return(void *addr, unsigned long val, int len)
 {
        switch (len) {
+#ifdef UATOMIC_HAS_ATOMIC_BYTE
+       case 1:
+       {
+               unsigned char old, oldt;
+
+               oldt = uatomic_read((unsigned char *)addr);
+               do {
+                       old = oldt;
+                       oldt = _uatomic_cmpxchg(addr, old, old + val, 1);
+               } while (oldt != old);
+
+               return old + val;
+       }
+#endif
+#ifdef UATOMIC_HAS_ATOMIC_SHORT
+       case 2:
+       {
+               unsigned short old, oldt;
+
+               oldt = uatomic_read((unsigned short *)addr);
+               do {
+                       old = oldt;
+                       oldt = _uatomic_cmpxchg(addr, old, old + val, 2);
+               } while (oldt != old);
+
+               return old + val;
+       }
+#endif
        case 4:
        {
                unsigned int old, oldt;
@@ -201,6 +269,34 @@ static inline __attribute__((always_inline))
 unsigned long _uatomic_exchange(void *addr, unsigned long val, int len)
 {
        switch (len) {
+#ifdef UATOMIC_HAS_ATOMIC_BYTE
+       case 1:
+       {
+               unsigned char old, oldt;
+
+               oldt = uatomic_read((unsigned char *)addr);
+               do {
+                       old = oldt;
+                       oldt = _uatomic_cmpxchg(addr, old, val, 1);
+               } while (oldt != old);
+
+               return old;
+       }
+#endif
+#ifdef UATOMIC_HAS_ATOMIC_SHORT
+       case 2:
+       {
+               unsigned short old, oldt;
+
+               oldt = uatomic_read((unsigned short *)addr);
+               do {
+                       old = oldt;
+                       oldt = _uatomic_cmpxchg(addr, old, val, 2);
+               } while (oldt != old);
+
+               return old;
+       }
+#endif
        case 4:
        {
                unsigned int old, oldt;
This page took 0.027974 seconds and 4 git commands to generate.