Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

atomic: better API, return result of operation

  • Loading branch information...
commit de04f58edfb3ce00f66d9db85574f529c8589710 1 parent 3e0157c
Fedor Indutny authored October 13, 2012

Showing 2 changed files with 24 additions and 17 deletions. Show diff stats Hide diff stats

  1. 37  src/atomic.h
  2. 4  src/lring.c
37  src/atomic.h
@@ -5,16 +5,18 @@
5 5
 #if defined(__GNUC__)
6 6
 # if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
7 7
 
8  
-#  define ATOMIC_ADD(arg, num) __sync_add_and_fetch(&arg, num)
9  
-#  define ATOMIC_SUB(arg, num) __sync_sub_and_fetch(&arg, num)
  8
+#  define ATOMIC_ADD(arg, num) __sync_add_and_fetch(arg, num)
  9
+#  define ATOMIC_SUB(arg, num) __sync_sub_and_fetch(arg, num)
10 10
 
11 11
 # elif defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || \
12 12
        defined( __i686__ ) || defined( __x86_64__ )
13 13
 
14  
-# define ATOMIC_ADD(arg, num)  asm volatile ("lock add %0, %1\n" : \
15  
-                                             : "r" (num), "m" (arg))
16  
-# define ATOMIC_SUB(arg, num)  asm volatile ("lock sub %0, %1\n" : \
17  
-                                             : "r" (num), "m" (arg))
  14
+# define ATOMIC_ADD(arg, num) asm volatile ("lock xadd %2, %1\n" : \
  15
+                                            "=m" (*arg) : \
  16
+                                            "m" (*arg), "r" (num))
  17
+# define ATOMIC_SUB(arg, num) asm volatile ("lock xadd %2, %1\n" : \
  18
+                                            "=m" (*arg) : \
  19
+                                            "m" (*arg), "r" (-num))
18 20
 
19 21
 # else
20 22
 
@@ -29,28 +31,33 @@
29 31
 # if defined( __x86_64__ ) || defined ( __ppc64__)
30 32
 #  define ATOMIC_CAST_WORD(arg) ((volatile int64_t*)(arg))
31 33
 
32  
-#  define ATOMIC_ADD(arg, num) OSAtomicAdd64(num, ATOMIC_CAST_WORD(&arg));
33  
-#  define ATOMIC_SUB(arg, num) OSAtomicAdd64(-num, ATOMIC_CAST_WORD(&arg));
  34
+#  define ATOMIC_ADD(arg, num) OSAtomicAdd64((num), ATOMIC_CAST_WORD((arg)))
  35
+#  define ATOMIC_SUB(arg, num) OSAtomicAdd64(-(num), ATOMIC_CAST_WORD((arg)))
34 36
 # else
35 37
 #  define ATOMIC_CAST_WORD(arg) ((volatile int32_t*)(arg))
36 38
 
37  
-#  define ATOMIC_ADD(arg, num) OSAtomicAdd32(num, ATOMIC_CAST_WORD(&arg));
38  
-#  define ATOMIC_SUB(arg, num) OSAtomicAdd32(-num, ATOMIC_CAST_WORD(&arg));
  39
+#  define ATOMIC_ADD(arg, num) OSAtomicAdd32((num), ATOMIC_CAST_WORD((arg)))
  40
+#  define ATOMIC_SUB(arg, num) OSAtomicAdd32(-(num), ATOMIC_CAST_WORD((arg)))
39 41
 # endif
40 42
 
41 43
 #elif defined(_MSC_VER)
42 44
 
43 45
 # if defined(_M_X64)
44  
-   extern "C" __int64 _InterlockedExchangeAdd64(__int64 volatile* addend, __int64 value);
  46
+   extern "C" __int64 _InterlockedExchangeAdd64(__int64 volatile* addend,
  47
+                                                __int64 value);
45 48
 #  pragma intrinsic (_InterlockedExchangeAdd64)
46  
-#  define ATOMIC_ADD(arg, num) ((void) _InterlockedExchangeAdd64(&(arg), (num)))
47  
-#  define ATOMIC_SUB(arg, num) ((void) _InterlockedExchangeAdd64(&(arg), -(num)))
  49
+#  define ATOMIC_ADD(arg, num) (_InterlockedExchangeAdd64((arg), (num)) + \
  50
+                                (num))
  51
+#  define ATOMIC_SUB(arg, num) (_InterlockedExchangeAdd64((arg), -(num)) - \
  52
+                                (num))
48 53
 
49 54
 # elif defined(_M_IX86)
50 55
    extern "C" long _InterlockedExchangeAdd(long volatile* addend, long value);
51 56
 #  pragma intrinsic (_InterlockedExchangeAdd)
52  
-#  define ATOMIC_ADD(arg, num) ((void) _InterlockedExchangeAdd(&(arg), (num)))
53  
-#  define ATOMIC_SUB(arg, num) ((void) _InterlockedExchangeAdd(&(arg), -(num)))
  57
+#  define ATOMIC_ADD(arg, num) (_InterlockedExchangeAdd(&(arg), (num)) + \
  58
+                                (num))
  59
+#  define ATOMIC_SUB(arg, num) (_InterlockedExchangeAdd(&(arg), -(num)) - \
  60
+                                (num))
54 61
 
55 62
 # else
56 63
 #  error Atomic operations are not supported on your platform
4  src/lring.c
@@ -100,7 +100,7 @@ void lring_write(lring_t* ring, const char* data, ssize_t size) {
100 100
     }
101 101
 
102 102
     PaUtil_WriteMemoryBarrier();
103  
-    ATOMIC_ADD(ring->total, bytes);
  103
+    ATOMIC_ADD(&ring->total, bytes);
104 104
   }
105 105
   assert(size == offset);
106 106
 }
@@ -135,7 +135,7 @@ ssize_t lring_read(lring_t* ring, char* data, ssize_t size) {
135 135
 
136 136
     roffset = p->roffset + bytes;
137 137
     p->roffset = roffset;
138  
-    ATOMIC_SUB(ring->total, bytes);
  138
+    ATOMIC_SUB(&ring->total, bytes);
139 139
 
140 140
     assert(roffset >= 0);
141 141
 

0 notes on commit de04f58

Please sign in to comment.
Something went wrong with that request. Please try again.