00001 #ifndef RUBY_ATOMIC_H
00002 #define RUBY_ATOMIC_H
00003
00004 #ifdef _WIN32
00005 #if defined _MSC_VER && _MSC_VER > 1200
00006 #pragma intrinsic(_InterlockedOr)
00007 #endif
00008 typedef LONG rb_atomic_t;
00009
00010 # define ATOMIC_SET(var, val) InterlockedExchange(&(var), (val))
00011 # define ATOMIC_INC(var) InterlockedIncrement(&(var))
00012 # define ATOMIC_DEC(var) InterlockedDecrement(&(var))
00013 #if defined __GNUC__
00014 # define ATOMIC_OR(var, val) __asm__("lock\n\t" "orl\t%1, %0" : "=m"(var) : "Ir"(val))
00015 #elif defined _MSC_VER && _MSC_VER <= 1200
00016 # define ATOMIC_OR(var, val) rb_w32_atomic_or(&(var), (val))
00017 static inline void
00018 rb_w32_atomic_or(volatile rb_atomic_t *var, rb_atomic_t val)
00019 {
00020 #ifdef _M_IX86
00021 __asm mov eax, var;
00022 __asm mov ecx, val;
00023 __asm lock or [eax], ecx;
00024 #else
00025 #error unsupported architecture
00026 #endif
00027 }
00028 #else
00029 # define ATOMIC_OR(var, val) _InterlockedOr(&(var), (val))
00030 #endif
00031 # define ATOMIC_EXCHANGE(var, val) InterlockedExchange(&(var), (val))
00032
00033 #elif defined HAVE_GCC_ATOMIC_BUILTINS
00034
00035
00036
00037
00038 typedef unsigned int rb_atomic_t;
00039 # define ATOMIC_SET(var, val) __sync_lock_test_and_set(&(var), (val))
00040 # define ATOMIC_INC(var) __sync_fetch_and_add(&(var), 1)
00041 # define ATOMIC_DEC(var) __sync_fetch_and_sub(&(var), 1)
00042 # define ATOMIC_OR(var, val) __sync_or_and_fetch(&(var), (val))
00043 # define ATOMIC_EXCHANGE(var, val) __sync_lock_test_and_set(&(var), (val))
00044
00045 #else
00046 typedef int rb_atomic_t;
00047 extern rb_atomic_t ruby_atomic_exchange(rb_atomic_t *ptr, rb_atomic_t val);
00048
00049 # define ATOMIC_SET(var, val) ((var) = (val))
00050 # define ATOMIC_INC(var) (++(var))
00051 # define ATOMIC_DEC(var) (--(var))
00052 # define ATOMIC_OR(var, val) ((var) |= (val))
00053 # define ATOMIC_EXCHANGE(var, val) ruby_atomic_exchange(&(var), (val))
00054 #endif
00055
00056 #endif
00057