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
00050 #ifndef UNIXSTL_INCL_UNIXSTL_SYNCH_H_ATOMIC_FUNCTIONS
00051 #define UNIXSTL_INCL_UNIXSTL_SYNCH_H_ATOMIC_FUNCTIONS
00052
00053 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00054 # define UNIXSTL_VER_UNIXSTL_SYNCH_H_ATOMIC_FUNCTIONS_MAJOR 6
00055 # define UNIXSTL_VER_UNIXSTL_SYNCH_H_ATOMIC_FUNCTIONS_MINOR 1
00056 # define UNIXSTL_VER_UNIXSTL_SYNCH_H_ATOMIC_FUNCTIONS_REVISION 1
00057 # define UNIXSTL_VER_UNIXSTL_SYNCH_H_ATOMIC_FUNCTIONS_EDIT 201
00058 #endif
00059
00060
00061
00062
00063
00064 #ifndef UNIXSTL_INCL_UNIXSTL_H_UNIXSTL
00065 # include <unixstl/unixstl.h>
00066 #endif
00067 #ifndef UNIXSTL_INCL_UNIXSTL_SYNCH_UTIL_H_FEATURES
00068 # include <unixstl/synch/util/features.h>
00069 #endif
00070 #ifndef UNIXSTL_INCL_UNIXSTL_SYNCH_H_ATOMIC_TYPES
00071 # include <unixstl/synch/atomic_types.h>
00072 #endif
00073
00074 #if defined(UNIXSTL_FORCE_ATOMIC_INTEGER_OPERATIONS)
00075
00076 #elif defined(UNIXSTL_ATOMIC_INTEGER_OPERATIONS_VIA_GCC_BUILTINS)
00077
00078 #elif defined(UNIXSTL_ATOMIC_INTEGER_OPERATIONS_VIA_MACOSX)
00079 # include <libkern/OSAtomic.h>
00080 #elif defined(UNIXSTL_ATOMIC_INTEGER_OPERATIONS_VIA_WINDOWS_INTERLOCKED)
00081 # include <windows.h>
00082 #else
00083 # error Atomic integer operations not supported: see unixstl/synch/util/features.h for details
00084 #endif
00085
00086
00087
00088
00089
00090 #ifndef _UNIXSTL_NO_NAMESPACE
00091 # if defined(_STLSOFT_NO_NAMESPACE) || \
00092 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00093
00094 namespace unixstl
00095 {
00096 # else
00097
00098
00099 namespace stlsoft
00100 {
00101
00102 namespace unixstl_project
00103 {
00104
00105 # endif
00106 #endif
00107
00108
00109
00110
00111
00112 #ifdef UNIXSTL_HAS_ATOMIC_PREINCREMENT
00113 # undef UNIXSTL_HAS_ATOMIC_PREINCREMENT
00114 #endif
00115 #ifdef UNIXSTL_HAS_ATOMIC_PREDECREMENT
00116 # undef UNIXSTL_HAS_ATOMIC_PREDECREMENT
00117 #endif
00118 #ifdef UNIXSTL_HAS_ATOMIC_POSTINCREMENT
00119 # undef UNIXSTL_HAS_ATOMIC_POSTINCREMENT
00120 #endif
00121 #ifdef UNIXSTL_HAS_ATOMIC_POSTDECREMENT
00122 # undef UNIXSTL_HAS_ATOMIC_POSTDECREMENT
00123 #endif
00124 #ifdef UNIXSTL_HAS_ATOMIC_INCREMENT
00125 # undef UNIXSTL_HAS_ATOMIC_INCREMENT
00126 #endif
00127 #ifdef UNIXSTL_HAS_ATOMIC_DECREMENT
00128 # undef UNIXSTL_HAS_ATOMIC_DECREMENT
00129 #endif
00130 #ifdef UNIXSTL_HAS_ATOMIC_READ
00131 # undef UNIXSTL_HAS_ATOMIC_READ
00132 #endif
00133 #ifdef UNIXSTL_HAS_ATOMIC_WRITE
00134 # undef UNIXSTL_HAS_ATOMIC_WRITE
00135 #endif
00136 #ifdef UNIXSTL_HAS_ATOMIC_PREADD
00137 # undef UNIXSTL_HAS_ATOMIC_PREADD
00138 #endif
00139 #ifdef UNIXSTL_HAS_ATOMIC_POSTADD
00140 # undef UNIXSTL_HAS_ATOMIC_POSTADD
00141 #endif
00142
00143
00144
00145
00146
00147 #if defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00148
00152 # define UNIXSTL_HAS_ATOMIC_PREINCREMENT
00153
00157 # define UNIXSTL_HAS_ATOMIC_PREDECREMENT
00158
00162 # define UNIXSTL_HAS_ATOMIC_POSTINCREMENT
00163
00167 # define UNIXSTL_HAS_ATOMIC_POSTDECREMENT
00168
00172 # define UNIXSTL_HAS_ATOMIC_INCREMENT
00173
00177 # define UNIXSTL_HAS_ATOMIC_DECREMENT
00178
00182 # define UNIXSTL_HAS_ATOMIC_READ
00183
00187 # define UNIXSTL_HAS_ATOMIC_WRITE
00188
00192 # define UNIXSTL_HAS_ATOMIC_PREADD
00193
00197 # define UNIXSTL_HAS_ATOMIC_POSTADD
00198
00199 #elif defined(UNIXSTL_HAS_ATOMIC_INTEGER_OPERATIONS)
00200
00201 # if defined(UNIXSTL_FORCE_ATOMIC_INTEGER_OPERATIONS)
00202
00203
00204
00205
00206
00207
00208 # ifndef UNIXSTL_FORCED_ATOMIC_INTEGER_IMPLEMENTATIONS
00209 # error If you are forcing atomic integer support (by defining UNIXSTL_FORCE_ATOMIC_INTEGER_OPERATIONS) you must also define UNIXSTL_FORCED_ATOMIC_INTEGER_IMPLEMENTATIONS as the header containing the atomic integer operations, which will be included
00210 # endif
00211 # include UNIXSTL_FORCED_ATOMIC_INTEGER_IMPLEMENTATIONS
00212
00213
00214 # elif defined(UNIXSTL_ATOMIC_INTEGER_OPERATIONS_VIA_GCC_BUILTINS)
00215
00216
00217
00218
00219
00220
00221 # error This feature is not yet supported, and you should not be seeing this compilation path unless unixstl/synch/util/features.h is out of synch with this file; contact Synesis Software
00222
00223
00224 # elif defined(UNIXSTL_ATOMIC_INTEGER_OPERATIONS_VIA_WINDOWS_INTERLOCKED)
00225
00226
00227
00228
00229
00230
00231 # if !defined(UNIXSTL_NO_WIN32_NATIVE_ATOMIC_FUNCTIONS)
00232
00233 STLSOFT_INLINE atomic_int_t atomic_preincrement(atomic_int_t volatile* pl)
00234 {
00235 return STLSOFT_NS_GLOBAL(InterlockedIncrement)((LPLONG)pl);
00236 }
00237 # define UNIXSTL_HAS_ATOMIC_PREINCREMENT
00238
00239 STLSOFT_INLINE atomic_int_t atomic_predecrement(atomic_int_t volatile* pl)
00240 {
00241 return STLSOFT_NS_GLOBAL(InterlockedDecrement)((LPLONG)pl);
00242 }
00243 # define UNIXSTL_HAS_ATOMIC_PREDECREMENT
00244
00245 STLSOFT_INLINE atomic_int_t atomic_postincrement(atomic_int_t volatile* pl)
00246 {
00247 atomic_int_t pre = *pl;
00248
00249 STLSOFT_NS_GLOBAL(InterlockedIncrement)((LPLONG)pl);
00250
00251 return pre;
00252 }
00253 # define UNIXSTL_HAS_ATOMIC_POSTINCREMENT
00254
00255 STLSOFT_INLINE atomic_int_t atomic_postdecrement(atomic_int_t volatile* pl)
00256 {
00257 atomic_int_t pre = *pl;
00258
00259 STLSOFT_NS_GLOBAL(InterlockedDecrement)((LPLONG)pl);
00260
00261 return pre;
00262 }
00263 # define UNIXSTL_HAS_ATOMIC_POSTDECREMENT
00264
00265 STLSOFT_INLINE void atomic_increment(atomic_int_t volatile* pl)
00266 {
00267 STLSOFT_NS_GLOBAL(InterlockedIncrement)((LPLONG)pl);
00268 }
00269 # define UNIXSTL_HAS_ATOMIC_INCREMENT
00270
00271 STLSOFT_INLINE void atomic_decrement(atomic_int_t volatile* pl)
00272 {
00273 STLSOFT_NS_GLOBAL(InterlockedDecrement)((LPLONG)pl);
00274 }
00275 # define UNIXSTL_HAS_ATOMIC_DECREMENT
00276
00277 # endif
00278
00279
00280
00281 STLSOFT_INLINE atomic_int_t atomic_write(atomic_int_t volatile* pv, atomic_int_t n)
00282 {
00283 return stlsoft_static_cast(atomic_int_t, STLSOFT_NS_GLOBAL(InterlockedExchange)(stlsoft_c_cast(LPLONG, pv), n));
00284 }
00285 # define UNIXSTL_HAS_ATOMIC_WRITE
00286
00287 # if !defined(UNIXSTL_NO_WIN32_NATIVE_ATOMIC_FUNCTIONS)
00288
00289 STLSOFT_INLINE atomic_int_t atomic_read(atomic_int_t volatile* pv)
00290 {
00291 return *pv;
00292 }
00293 # define UNIXSTL_HAS_ATOMIC_READ
00294
00295 atomic_int_t atomic_preadd(atomic_int_t volatile* pl, atomic_int_t n);
00296
00297 STLSOFT_INLINE atomic_int_t atomic_postadd(atomic_int_t volatile* pl, atomic_int_t n)
00298 {
00299 return (atomic_int_t)STLSOFT_NS_GLOBAL(InterlockedExchangeAdd)((LPLONG)pl, n);
00300 }
00301 # define UNIXSTL_HAS_ATOMIC_POSTADD
00302
00303 # endif
00304
00305
00306 # elif defined(UNIXSTL_ATOMIC_INTEGER_OPERATIONS_VIA_MACOSX)
00307
00308
00309
00310
00311
00312
00317 STLSOFT_INLINE atomic_int_t atomic_preincrement(atomic_int_t volatile* pl)
00318 {
00319 return STLSOFT_NS_GLOBAL(OSAtomicIncrement32Barrier)(stlsoft_const_cast(atomic_int_t*, pl));
00320 }
00321 # define UNIXSTL_HAS_ATOMIC_PREINCREMENT
00322
00327 STLSOFT_INLINE atomic_int_t atomic_predecrement(atomic_int_t volatile* pl)
00328 {
00329 return STLSOFT_NS_GLOBAL(OSAtomicDecrement32Barrier)(stlsoft_const_cast(atomic_int_t*, pl));
00330 }
00331 # define UNIXSTL_HAS_ATOMIC_PREDECREMENT
00332
00337 STLSOFT_INLINE atomic_int_t atomic_postincrement(atomic_int_t volatile* pl)
00338 {
00339 return STLSOFT_NS_GLOBAL(OSAtomicIncrement32Barrier)(stlsoft_const_cast(atomic_int_t*, pl)) - 1;
00340 }
00341 # define UNIXSTL_HAS_ATOMIC_POSTINCREMENT
00342
00347 STLSOFT_INLINE atomic_int_t atomic_postdecrement(atomic_int_t volatile* pl)
00348 {
00349 return STLSOFT_NS_GLOBAL(OSAtomicDecrement32Barrier)(stlsoft_const_cast(atomic_int_t*, pl)) + 1;
00350 }
00351 # define UNIXSTL_HAS_ATOMIC_POSTDECREMENT
00352
00357 STLSOFT_INLINE void atomic_increment(atomic_int_t volatile* pl)
00358 {
00359 STLSOFT_NS_GLOBAL(OSAtomicIncrement32Barrier)(stlsoft_const_cast(atomic_int_t*, pl));
00360 }
00361 # define UNIXSTL_HAS_ATOMIC_INCREMENT
00362
00367 STLSOFT_INLINE void atomic_decrement(atomic_int_t volatile* pl)
00368 {
00369 STLSOFT_NS_GLOBAL(OSAtomicDecrement32Barrier)(stlsoft_const_cast(atomic_int_t*, pl));
00370 }
00371 # define UNIXSTL_HAS_ATOMIC_DECREMENT
00372
00382 atomic_int_t atomic_write(atomic_int_t volatile* pv, atomic_int_t n);
00383
00388 STLSOFT_INLINE atomic_int_t atomic_read(atomic_int_t volatile* pv)
00389 {
00390 STLSOFT_NS_GLOBAL(OSMemoryBarrier)();
00391
00392 return *pv;
00393 }
00394 # define UNIXSTL_HAS_ATOMIC_READ
00395
00400 STLSOFT_INLINE atomic_int_t atomic_preadd(atomic_int_t volatile* pl, atomic_int_t n)
00401 {
00402 return STLSOFT_NS_GLOBAL(OSAtomicAdd32Barrier)(n, stlsoft_const_cast(atomic_int_t*, pl));
00403 }
00404 # define UNIXSTL_HAS_ATOMIC_PREADD
00405
00410 STLSOFT_INLINE atomic_int_t atomic_postadd(atomic_int_t volatile* pl, atomic_int_t n)
00411 {
00412 return STLSOFT_NS_GLOBAL(OSAtomicAdd32Barrier)(n, stlsoft_const_cast(atomic_int_t*, pl)) - n;
00413 }
00414 # define UNIXSTL_HAS_ATOMIC_POSTADD
00415
00416
00417 # else
00418 # error Atomic integer operations not supported: see unixstl/synch/util/features.h for details
00419 # endif
00420
00421
00422
00423
00424 # if 0
00425
00426 STLSOFT_INLINE atomic_int_t atomic_read(atomic_int_t volatile* pv);
00427
00428
00429
00430 STLSOFT_INLINE atomic_int_t atomic_write(atomic_int_t volatile* pv, atomic_int_t n)
00431 {
00432 atomic_int_t oldval;
00433
00434
00435 # ifdef STLSOFT_COMPILER_IS_GCC
00436 __asm__ __volatile__( "xchgl %0, %1"
00437 : "=r"(oldval), "=m"(*(pv))
00438 : "0"(n), "m"(*(pv))
00439 : "memory");
00440 # else
00441 _asm
00442 {
00443 mov ecx, dword ptr [pv]
00444 mov eax, n
00445 xchg dword ptr [ecx], eax
00446 mov oldval, eax
00447 }
00448 # endif
00449
00450 return oldval;
00451 }
00452
00453 #endif
00454
00455
00456
00457 #endif
00458
00459
00460
00461
00462
00463 #ifdef STLSOFT_UNITTEST
00464 # include "./unittest/atomic_functions_unittest_.h"
00465 #endif
00466
00467
00468
00469 #ifndef _UNIXSTL_NO_NAMESPACE
00470 # if defined(_STLSOFT_NO_NAMESPACE) || \
00471 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00472 }
00473 # else
00474 }
00475 }
00476 # endif
00477 #endif
00478
00479
00480
00481 #endif
00482
00483