00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #ifndef APR_ATOMIC_H
00060 #define APR_ATOMIC_H
00061
00067 #include "apr.h"
00068 #include "apr_pools.h"
00069
00070
00071 #if defined(NETWARE) || defined(__MVS__)
00072 #include <stdlib.h>
00073 #elif defined(__FreeBSD__)
00074 #include <machine/atomic.h>
00075 #endif
00076
00077 #ifdef __cplusplus
00078 extern "C" {
00079 #endif
00080
00087
00088 #if defined(DOXYGEN)
00089
00093 typedef apr_atomic_t;
00094
00101 apr_status_t apr_atomic_init(apr_pool_t *p);
00108 apr_uint32_t apr_atomic_read(volatile apr_atomic_t *mem);
00114 void apr_atomic_set(volatile apr_atomic_t *mem, apr_uint32_t val);
00120 void apr_atomic_add(volatile apr_atomic_t *mem, apr_uint32_t val);
00121
00126 void apr_atomic_inc(volatile apr_atomic_t *mem);
00127
00133 int apr_atomic_dec(volatile apr_atomic_t *mem);
00134
00145 apr_uint32_t apr_atomic_cas(volatile apr_uint32_t *mem, long with, long cmp);
00146
00155 void *apr_atomic_casptr(volatile void **mem, void *with, const void *cmp);
00156 #else
00157
00158
00159
00160
00161
00162
00163
00164
00165 #if defined(WIN32)
00166
00167 #define apr_atomic_t LONG
00168
00169 #define apr_atomic_add(mem, val) InterlockedExchangeAdd(mem,val)
00170 #define apr_atomic_dec(mem) InterlockedDecrement(mem)
00171 #define apr_atomic_inc(mem) InterlockedIncrement(mem)
00172 #define apr_atomic_set(mem, val) InterlockedExchange(mem, val)
00173 #define apr_atomic_read(mem) (*mem)
00174 #define apr_atomic_cas(mem,with,cmp) InterlockedCompareExchange(mem,with,cmp)
00175 #define apr_atomic_init(pool) APR_SUCCESS
00176 #define apr_atomic_casptr(mem,with,cmp) InterlockedCompareExchangePointer(mem,with,cmp)
00177
00178 #elif defined(NETWARE)
00179
00180 #define apr_atomic_t unsigned long
00181
00182 #define apr_atomic_add(mem, val) atomic_add(mem,val)
00183 #define apr_atomic_inc(mem) atomic_inc(mem)
00184 #define apr_atomic_set(mem, val) (*mem = val)
00185 #define apr_atomic_read(mem) (*mem)
00186 #define apr_atomic_init(pool) APR_SUCCESS
00187 #define apr_atomic_cas(mem,with,cmp) atomic_cmpxchg((unsigned long *)(mem),(unsigned long)(cmp),(unsigned long)(with))
00188
00189 int apr_atomic_dec(apr_atomic_t *mem);
00190 void *apr_atomic_casptr(void **mem, void *with, const void *cmp);
00191 #define APR_OVERRIDE_ATOMIC_DEC 1
00192 #define APR_OVERRIDE_ATOMIC_CASPTR 1
00193
00194 inline int apr_atomic_dec(apr_atomic_t *mem)
00195 {
00196 atomic_dec(mem);
00197 return *mem;
00198 }
00199
00200 inline void *apr_atomic_casptr(void **mem, void *with, const void *cmp)
00201 {
00202 return (void*)atomic_cmpxchg((unsigned long *)mem,(unsigned long)cmp,(unsigned long)with);
00203 }
00204
00205 #elif defined(__FreeBSD__)
00206
00207 #define apr_atomic_t apr_uint32_t
00208 #define apr_atomic_add(mem, val) atomic_add_int(mem,val)
00209 #define apr_atomic_dec(mem) atomic_subtract_int(mem,1)
00210 #define apr_atomic_inc(mem) atomic_add_int(mem,1)
00211 #define apr_atomic_set(mem, val) atomic_set_int(mem, val)
00212 #define apr_atomic_read(mem) (*mem)
00213
00214 #elif (defined(__linux__) || defined(__EMX__)) && defined(__i386__) && !APR_FORCE_ATOMIC_GENERIC
00215
00216 #define apr_atomic_t apr_uint32_t
00217 #define apr_atomic_cas(mem,with,cmp) \
00218 ({ apr_atomic_t prev; \
00219 asm volatile ("lock; cmpxchgl %1, %2" \
00220 : "=a" (prev) \
00221 : "r" (with), "m" (*(mem)), "0"(cmp) \
00222 : "memory"); \
00223 prev;})
00224
00225 #define apr_atomic_add(mem, val) \
00226 ({ register apr_atomic_t last; \
00227 do { \
00228 last = *(mem); \
00229 } while (apr_atomic_cas((mem), last + (val), last) != last); \
00230 })
00231
00232 #define apr_atomic_dec(mem) \
00233 ({ register apr_atomic_t last; \
00234 do { \
00235 last = *(mem); \
00236 } while (apr_atomic_cas((mem), last - 1, last) != last); \
00237 (--last != 0); })
00238
00239 #define apr_atomic_inc(mem) \
00240 ({ register apr_atomic_t last; \
00241 do { \
00242 last = *(mem); \
00243 } while (apr_atomic_cas((mem), last + 1, last) != last); \
00244 })
00245
00246 #define apr_atomic_set(mem, val) (*(mem) = val)
00247 #define apr_atomic_read(mem) (*(mem))
00248 #define apr_atomic_init(pool) APR_SUCCESS
00249
00250 #elif defined(__MVS__)
00251
00252 #define apr_atomic_t cs_t
00253
00254 apr_int32_t apr_atomic_add(volatile apr_atomic_t *mem, apr_int32_t val);
00255 apr_uint32_t apr_atomic_cas(volatile apr_atomic_t *mem, apr_uint32_t swap,
00256 apr_uint32_t cmp);
00257 #define APR_OVERRIDE_ATOMIC_ADD 1
00258 #define APR_OVERRIDE_ATOMIC_CAS 1
00259
00260 #define apr_atomic_inc(mem) apr_atomic_add(mem, 1)
00261 #define apr_atomic_dec(mem) apr_atomic_add(mem, -1)
00262 #define apr_atomic_init(pool) APR_SUCCESS
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 #define apr_atomic_read(p) (*p)
00274 #define apr_atomic_set(mem, val) (*mem = val)
00275
00276 #endif
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 #if !defined(apr_atomic_t)
00290 #define apr_atomic_t apr_uint32_t
00291 #endif
00292
00293 #if !defined(apr_atomic_init) && !defined(APR_OVERRIDE_ATOMIC_INIT)
00294 apr_status_t apr_atomic_init(apr_pool_t *p);
00295 #endif
00296
00297 #if !defined(apr_atomic_read) && !defined(APR_OVERRIDE_ATOMIC_READ)
00298 #define apr_atomic_read(p) *p
00299 #endif
00300
00301 #if !defined(apr_atomic_set) && !defined(APR_OVERRIDE_ATOMIC_SET)
00302 void apr_atomic_set(volatile apr_atomic_t *mem, apr_uint32_t val);
00303 #define APR_ATOMIC_NEED_DEFAULT_INIT 1
00304 #endif
00305
00306 #if !defined(apr_atomic_add) && !defined(APR_OVERRIDE_ATOMIC_ADD)
00307 void apr_atomic_add(volatile apr_atomic_t *mem, apr_uint32_t val);
00308 #define APR_ATOMIC_NEED_DEFAULT_INIT 1
00309 #endif
00310
00311 #if !defined(apr_atomic_inc) && !defined(APR_OVERRIDE_ATOMIC_INC)
00312 void apr_atomic_inc(volatile apr_atomic_t *mem);
00313 #define APR_ATOMIC_NEED_DEFAULT_INIT 1
00314 #endif
00315
00316 #if !defined(apr_atomic_dec) && !defined(APR_OVERRIDE_ATOMIC_DEC)
00317 int apr_atomic_dec(volatile apr_atomic_t *mem);
00318 #define APR_ATOMIC_NEED_DEFAULT_INIT 1
00319 #endif
00320
00321 #if !defined(apr_atomic_cas) && !defined(APR_OVERRIDE_ATOMIC_CAS)
00322 apr_uint32_t apr_atomic_cas(volatile apr_uint32_t *mem,long with,long cmp);
00323 #define APR_ATOMIC_NEED_DEFAULT_INIT 1
00324 #endif
00325
00326 #if !defined(apr_atomic_casptr) && !defined(APR_OVERRIDE_ATOMIC_CASPTR)
00327 #if APR_SIZEOF_VOIDP == 4
00328 #define apr_atomic_casptr(mem, with, cmp) (void *)apr_atomic_cas((apr_uint32_t *)(mem), (long)(with), (long)cmp)
00329 #else
00330 void *apr_atomic_casptr(volatile void **mem, void *with, const void *cmp);
00331 #define APR_ATOMIC_NEED_DEFAULT_INIT 1
00332 #endif
00333 #endif
00334
00335 #ifndef APR_ATOMIC_NEED_DEFAULT_INIT
00336 #define APR_ATOMIC_NEED_DEFAULT_INIT 0
00337 #endif
00338
00339
00340
00341
00342
00343 #if APR_ATOMIC_NEED_DEFAULT_INIT
00344 #if defined(apr_atomic_init) || defined(APR_OVERRIDE_ATOMIC_INIT)
00345 #error Platform has redefined apr_atomic_init, but other default default atomics require a default apr_atomic_init
00346 #endif
00347 #endif
00348
00349 #endif
00350
00353 #ifdef __cplusplus
00354 }
00355 #endif
00356
00357 #endif