root/src/utils/noit_atomic.h

Revision 0b1d2f2e094f32ac6912ecb9d3d2189fe811c7da, 5.8 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 6 years ago)

addresses a lot of warnings. gcc still complains about stuff in xpath stuff, doesn't look like our code though, refs #34

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  */
5
6 #ifndef UTILS_NOIT_ATOMIC_H
7 #define UTILS_NOIT_ATOMIC_H
8
9 #include "noit_config.h"
10
11 typedef int32_t noit_atomic32_t;
12 typedef int64_t noit_atomic64_t;
13
14 #ifdef HAVE_LIBKERN_OSATOMIC_H
15 /*
16  * This secion is for Darwin.
17  * And we simply don't run on 32bit PPC.  Life's a bitch.
18  */
19 #include <libkern/OSAtomic.h>
20 typedef OSSpinLock noit_spinlock_t;
21 #define noit_atomic_cas32(ref,new,old) (OSAtomicCompareAndSwap32(old,new,ref) ? old : new)
22 #define noit_atomic_cas64(ref,new,old) (OSAtomicCompareAndSwap64(old,new,ref) ? old : new)
23 #define noit_atomic_casptr(ref,new,old) (OSAtomicCompareAndSwapPtr(old,new,ref) ? old : new)
24 #define noit_atomic_add32(ref,diff) OSAtomicAdd32(ref,diff)
25 #define noit_atomic_add64(ref,diff) OSAtomicAdd64(ref,diff)
26 #define noit_atomic_sub32(ref,diff) OSAtomicAdd32(ref,0-(diff))
27 #define noit_atomic_sub64(ref,diff) OSAtomicAdd64(ref,0-(diff))
28 #define noit_atomic_inc32(ref) OSAtomicIncrement32(ref)
29 #define noit_atomic_inc64(ref) OSAtomicIncrement64(ref)
30 #define noit_atomic_dec32(ref) OSAtomicDecrement32(ref)
31 #define noit_atomic_dec64(ref) OSAtomicDecrement64(ref)
32 #define noit_spinlock_lock OSSpinLockLock
33 #define noit_spinlock_unlock OSSpinLockUnlock
34 #define noit_spinlock_trylock OSSpinLockTry
35 #elif defined(__GNUC__)
36
37 #if (SIZEOF_VOID_P == 4)
38 #define noit_atomic_casptr(a,b,c) noit_atomic_cas32((vpsized_int *)(a),(vpsized_int)(void *)(b),(vpsized_int)(void *)(c))
39 #elif (SIZEOF_VOID_P == 8)
40 #define noit_atomic_casptr(a,b,c) noit_atomic_cas64((vpsized_int *)(a),(vpsized_int)(void *)(b),(vpsized_int)(void *)(c))
41 #else
42 #error unsupported pointer width
43 #endif
44
45
46 typedef noit_atomic32_t noit_spinlock_t;
47
48 static inline noit_atomic32_t
49 noit_atomic_cas32(volatile noit_atomic32_t *ptr,
50                   volatile noit_atomic32_t rpl,
51                   volatile noit_atomic32_t curr) {
52   noit_atomic32_t prev;
53   __asm__ volatile (
54       "lock; cmpxchgl %1, %2"
55     : "=a" (prev)
56     : "r"  (rpl), "m" (*(ptr)), "0" (curr)
57     : "memory");
58   return prev;
59 }
60
61 #ifdef __x86_64__
62 static inline noit_atomic64_t
63 noit_atomic_cas64(volatile noit_atomic64_t *ptr,
64                   volatile noit_atomic64_t rpl,
65                   volatile noit_atomic64_t curr) {
66   noit_atomic64_t prev;
67   __asm__ volatile (
68       "lock; cmpxchgq %1, %2"
69     : "=a" (prev)
70     : "r"  (rpl), "m" (*(ptr)), "0" (curr)
71     : "memory");
72   return prev;
73 }
74 #else
75 static inline noit_atomic64_t
76 noit_atomic_cas64(volatile noit_atomic64_t *ptr,
77                   volatile noit_atomic64_t rpl,
78                   volatile noit_atomic64_t curr) {
79   noit_atomic64_t prev;
80   __asm__ volatile (
81       "pushl %%ebx;"
82       "mov 4+%1,%%ecx;"
83       "mov %1,%%ebx;"
84       "lock;"
85       "cmpxchg8b (%3);"
86       "popl %%ebx"
87     : "=A" (prev)
88     : "m" (rpl), "A" (curr), "r" (ptr)
89     : "%ecx", "memory");
90   return prev;
91 };
92 #endif
93
94 static inline void noit_spinlock_lock(volatile noit_spinlock_t *lock) {
95   while(noit_atomic_cas32(lock, 1, 0) != 0);
96 }
97 static inline void noit_spinlock_unlock(volatile noit_spinlock_t *lock) {
98   while(noit_atomic_cas32(lock, 0, 1) != 1);
99 }
100 static inline int noit_spinlock_trylock(volatile noit_spinlock_t *lock) {
101   return (noit_atomic_cas32(lock, 1, 0) == 0);
102 }
103
104 #elif (defined(__amd64) || defined(__i386)) && (defined(__SUNPRO_C) || defined(__SUNPRO_CC))
105
106 typedef noit_atomic32_t noit_spinlock_t;
107
108 extern noit_atomic32_t noit_atomic_cas32(volatile noit_atomic32_t *mem,
109         volatile noit_atomic32_t newval, volatile noit_atomic32_t cmpval);
110 extern noit_atomic64_t noit_atomic_cas64(volatile noit_atomic64_t *mem,
111         volatile noit_atomic64_t newval, volatile noit_atomic64_t cmpval);
112
113 static inline void noit_spinlock_lock(volatile noit_spinlock_t *lock) {
114   while(noit_atomic_cas32(lock, 1, 0) != 0);
115 }
116 static inline void noit_spinlock_unlock(volatile noit_spinlock_t *lock) {
117   while(noit_atomic_cas32(lock, 0, 1) != 1);
118 }
119 static inline int noit_spinlock_trylock(volatile noit_spinlock_t *lock) {
120   return (noit_atomic_cas32(lock, 1, 0) == 0);
121 }
122
123 #else
124 #error Please stub out the atomics section for your platform
125 #endif
126
127 #ifndef noit_atomic_add32
128 static inline noit_atomic32_t noit_atomic_add32(volatile noit_atomic32_t *loc,
129                                                 volatile noit_atomic32_t diff) {
130   register noit_atomic32_t current;
131   do {
132     current = *(loc);
133   } while(noit_atomic_cas32(loc, current + diff, current) != current);
134   return current + diff;
135 }
136 #endif
137
138 #ifndef noit_atomic_add64
139 static inline noit_atomic64_t noit_atomic_add64(volatile noit_atomic64_t *loc,
140                                                 volatile noit_atomic64_t diff) {
141   register noit_atomic64_t current;
142   do {
143     current = *(loc);
144   } while(noit_atomic_cas64(loc, current + diff, current) != current);
145   return current + diff;
146 }
147 #endif
148
149 #ifndef noit_atomic_sub32
150 static inline noit_atomic32_t noit_atomic_sub32(volatile noit_atomic32_t *loc,
151                                                 volatile noit_atomic32_t diff) {
152   register noit_atomic32_t current;
153   do {
154     current = *(loc);
155   } while(noit_atomic_cas32(loc, current - diff, current) != current);
156   return current - diff;
157 }
158 #endif
159
160 #ifndef noit_atomic_sub64
161 static inline noit_atomic64_t noit_atomic_sub64(volatile noit_atomic64_t *loc,
162                                                 volatile noit_atomic64_t diff) {
163   register noit_atomic64_t current;
164   do {
165     current = *(loc);
166   } while(noit_atomic_cas64(loc, current - diff, current) != current);
167   return current - diff;
168 }
169 #endif
170
171 #ifndef noit_atomic_inc32
172 #define noit_atomic_inc32(a) noit_atomic_add32(a, 1)
173 #endif
174
175 #ifndef noit_atomic_inc64
176 #define noit_atomic_inc64(a) noit_atomic_add64(a, 1)
177 #endif
178
179 #ifndef noit_atomic_dec32
180 #define noit_atomic_dec32(a) noit_atomic_add32(a, -1)
181 #endif
182
183 #ifndef noit_atomic_dec64
184 #define noit_atomic_dec64(a) noit_atomic_add64(a, -1)
185 #endif
186
187 #endif
Note: See TracBrowser for help on using the browser.