00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef APR_ATOMIC_H
00018 #define APR_ATOMIC_H
00019
00025 #include "apr.h"
00026 #include "apr_pools.h"
00027
00028
00029 #if defined(NETWARE) || defined(__MVS__)
00030 #include <stdlib.h>
00031 #elif defined(__FreeBSD__)
00032 #include <machine/atomic.h>
00033 #endif
00034
00035 #ifdef __cplusplus
00036 extern "C" {
00037 #endif
00038
00045
00046 #if defined(DOXYGEN)
00047
00051 typedef apr_atomic_t;
00052
00059 apr_status_t apr_atomic_init(apr_pool_t *p);
00066 apr_uint32_t apr_atomic_read(volatile apr_atomic_t *mem);
00072 void apr_atomic_set(volatile apr_atomic_t *mem, apr_uint32_t val);
00078 void apr_atomic_add(volatile apr_atomic_t *mem, apr_uint32_t val);
00079
00084 void apr_atomic_inc(volatile apr_atomic_t *mem);
00085
00091 int apr_atomic_dec(volatile apr_atomic_t *mem);
00092
00103 apr_uint32_t apr_atomic_cas(volatile apr_uint32_t *mem, long with, long cmp);
00104
00113 void *apr_atomic_casptr(volatile void **mem, void *with, const void *cmp);
00114 #else
00115
00116
00117
00118
00119
00120
00121
00122
00123 #if defined(WIN32)
00124
00125 #define apr_atomic_t LONG
00126
00127 #define apr_atomic_add(mem, val) InterlockedExchangeAdd(mem,val)
00128 #define apr_atomic_dec(mem) InterlockedDecrement(mem)
00129 #define apr_atomic_inc(mem) InterlockedIncrement(mem)
00130 #define apr_atomic_set(mem, val) InterlockedExchange(mem, val)
00131 #define apr_atomic_read(mem) (*mem)
00132 #define apr_atomic_cas(mem,with,cmp) InterlockedCompareExchange(mem,with,cmp)
00133 #define apr_atomic_init(pool) APR_SUCCESS
00134 #define apr_atomic_casptr(mem,with,cmp) InterlockedCompareExchangePointer(mem,with,cmp)
00135
00136 #elif defined(NETWARE)
00137
00138 #define apr_atomic_t unsigned long
00139
00140 #define apr_atomic_add(mem, val) atomic_add(mem,val)
00141 #define apr_atomic_inc(mem) atomic_inc(mem)
00142 #define apr_atomic_set(mem, val) (*mem = val)
00143 #define apr_atomic_read(mem) (*mem)
00144 #define apr_atomic_init(pool) APR_SUCCESS
00145 #define apr_atomic_cas(mem,with,cmp) atomic_cmpxchg((unsigned long *)(mem),(unsigned long)(cmp),(unsigned long)(with))
00146
00147 int apr_atomic_dec(apr_atomic_t *mem);
00148 void *apr_atomic_casptr(void **mem, void *with, const void *cmp);
00149 #define APR_OVERRIDE_ATOMIC_DEC 1
00150 #define APR_OVERRIDE_ATOMIC_CASPTR 1
00151
00152 inline int apr_atomic_dec(apr_atomic_t *mem)
00153 {
00154 return (atomic_xchgadd(mem, 0xFFFFFFFF) - 1);
00155 }
00156
00157 inline void *apr_atomic_casptr(void **mem, void *with, const void *cmp)
00158 {
00159 return (void*)atomic_cmpxchg((unsigned long *)mem,(unsigned long)cmp,(unsigned long)with);
00160 }
00161
00162 #elif defined(__FreeBSD__)
00163
00164 #define apr_atomic_t apr_uint32_t
00165 #define apr_atomic_add(mem, val) (atomic_add_int(mem,val),mem)
00166 #define apr_atomic_dec(mem) (atomic_subtract_int(mem,1),mem)
00167 #define apr_atomic_inc(mem) (atomic_add_int(mem,1),mem)
00168 #define apr_atomic_set(mem, val) (atomic_set_int(mem, val),mem)
00169 #define apr_atomic_read(mem) (*mem)
00170
00171 #elif (defined(__linux__) || defined(__EMX__)) && defined(__i386__) && !APR_FORCE_ATOMIC_GENERIC
00172
00173 #define apr_atomic_t apr_uint32_t
00174 #define apr_atomic_cas(mem,with,cmp) \
00175 ({ apr_atomic_t prev; \
00176 asm volatile ("lock; cmpxchgl %1, %2" \
00177 : "=a" (prev) \
00178 : "r" (with), "m" (*(mem)), "0"(cmp) \
00179 : "memory"); \
00180 prev;})
00181
00182 #define apr_atomic_add(mem, val) \
00183 ({ register apr_atomic_t last; \
00184 do { \
00185 last = *(mem); \
00186 } while (apr_atomic_cas((mem), last + (val), last) != last); \
00187 })
00188
00189 #define apr_atomic_dec(mem) \
00190 ({ register apr_atomic_t last; \
00191 do { \
00192 last = *(mem); \
00193 } while (apr_atomic_cas((mem), last - 1, last) != last); \
00194 (--last != 0); })
00195
00196 #define apr_atomic_inc(mem) \
00197 ({ register apr_atomic_t last; \
00198 do { \
00199 last = *(mem); \
00200 } while (apr_atomic_cas((mem), last + 1, last) != last); \
00201 })
00202
00203 #define apr_atomic_set(mem, val) (*(mem) = val)
00204 #define apr_atomic_read(mem) (*(mem))
00205 #define apr_atomic_init(pool) APR_SUCCESS
00206
00207 #elif defined(__MVS__)
00208
00209 #define apr_atomic_t cs_t
00210
00211 apr_int32_t apr_atomic_add(volatile apr_atomic_t *mem, apr_int32_t val);
00212 apr_uint32_t apr_atomic_cas(volatile apr_atomic_t *mem, apr_uint32_t swap,
00213 apr_uint32_t cmp);
00214 #define APR_OVERRIDE_ATOMIC_ADD 1
00215 #define APR_OVERRIDE_ATOMIC_CAS 1
00216
00217 #define apr_atomic_inc(mem) apr_atomic_add(mem, 1)
00218 #define apr_atomic_dec(mem) apr_atomic_add(mem, -1)
00219 #define apr_atomic_init(pool) APR_SUCCESS
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 #define apr_atomic_read(p) (*p)
00231 #define apr_atomic_set(mem, val) (*mem = val)
00232
00233 #endif
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 #if !defined(apr_atomic_t)
00247 #define apr_atomic_t apr_uint32_t
00248 #endif
00249
00250 #if !defined(apr_atomic_init) && !defined(APR_OVERRIDE_ATOMIC_INIT)
00251 apr_status_t apr_atomic_init(apr_pool_t *p);
00252 #endif
00253
00254 #if !defined(apr_atomic_read) && !defined(APR_OVERRIDE_ATOMIC_READ)
00255 #define apr_atomic_read(p) *p
00256 #endif
00257
00258 #if !defined(apr_atomic_set) && !defined(APR_OVERRIDE_ATOMIC_SET)
00259 void apr_atomic_set(volatile apr_atomic_t *mem, apr_uint32_t val);
00260 #define APR_ATOMIC_NEED_DEFAULT_INIT 1
00261 #endif
00262
00263 #if !defined(apr_atomic_add) && !defined(APR_OVERRIDE_ATOMIC_ADD)
00264 void apr_atomic_add(volatile apr_atomic_t *mem, apr_uint32_t val);
00265 #define APR_ATOMIC_NEED_DEFAULT_INIT 1
00266 #endif
00267
00268 #if !defined(apr_atomic_inc) && !defined(APR_OVERRIDE_ATOMIC_INC)
00269 void apr_atomic_inc(volatile apr_atomic_t *mem);
00270 #define APR_ATOMIC_NEED_DEFAULT_INIT 1
00271 #endif
00272
00273 #if !defined(apr_atomic_dec) && !defined(APR_OVERRIDE_ATOMIC_DEC)
00274 int apr_atomic_dec(volatile apr_atomic_t *mem);
00275 #define APR_ATOMIC_NEED_DEFAULT_INIT 1
00276 #endif
00277
00278 #if !defined(apr_atomic_cas) && !defined(APR_OVERRIDE_ATOMIC_CAS)
00279 apr_uint32_t apr_atomic_cas(volatile apr_uint32_t *mem,long with,long cmp);
00280 #define APR_ATOMIC_NEED_DEFAULT_INIT 1
00281 #endif
00282
00283 #if !defined(apr_atomic_casptr) && !defined(APR_OVERRIDE_ATOMIC_CASPTR)
00284 #if APR_SIZEOF_VOIDP == 4
00285 #define apr_atomic_casptr(mem, with, cmp) (void *)apr_atomic_cas((apr_uint32_t *)(mem), (long)(with), (long)cmp)
00286 #else
00287 void *apr_atomic_casptr(volatile void **mem, void *with, const void *cmp);
00288 #define APR_ATOMIC_NEED_DEFAULT_INIT 1
00289 #endif
00290 #endif
00291
00292 #ifndef APR_ATOMIC_NEED_DEFAULT_INIT
00293 #define APR_ATOMIC_NEED_DEFAULT_INIT 0
00294 #endif
00295
00296
00297
00298
00299
00300 #if APR_ATOMIC_NEED_DEFAULT_INIT
00301 #if defined(apr_atomic_init) || defined(APR_OVERRIDE_ATOMIC_INIT)
00302 #error Platform has redefined apr_atomic_init, but other default default atomics require a default apr_atomic_init
00303 #endif
00304 #endif
00305
00306 #endif
00307
00310 #ifdef __cplusplus
00311 }
00312 #endif
00313
00314 #endif