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