Go to the documentation of this file.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 #ifndef _ink_atomic_h_
00038 #define _ink_atomic_h_
00039 
00040 #include <stdio.h>
00041 #include <string.h>
00042 #include <stdint.h>
00043 #include <assert.h>
00044 #include "ink_defs.h"
00045 
00046 #include "ink_apidefs.h"
00047 #include "ink_mutex.h"
00048 
00049 typedef volatile int8_t vint8;
00050 typedef volatile int16_t vint16;
00051 typedef volatile int32_t vint32;
00052 typedef volatile int64_t vint64;
00053 typedef volatile uint64_t vuint64;
00054 typedef volatile long vlong;
00055 typedef volatile void *vvoidp;
00056 
00057 typedef vint8 *pvint8;
00058 typedef vint16 *pvint16;
00059 typedef vint32 *pvint32;
00060 typedef vint64 *pvint64;
00061 typedef vuint64 *pvuint64;
00062 typedef vlong *pvlong;
00063 typedef vvoidp *pvvoidp;
00064 
00065 
00066 #if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
00067 
00068 
00069 
00070 
00071 
00072 template <typename T> static inline T
00073 ink_atomic_swap(volatile T * mem, T value) {
00074   return __sync_lock_test_and_set(mem, value);
00075 }
00076 
00077 
00078 
00079 
00080 template <typename T> static inline bool
00081 ink_atomic_cas(volatile T * mem, T prev, T next) {
00082   return __sync_bool_compare_and_swap(mem, prev, next);
00083 }
00084 
00085 
00086 
00087 template <typename Type, typename Amount> static inline Type
00088 ink_atomic_increment(volatile Type * mem, Amount count) {
00089   return __sync_fetch_and_add(mem, (Type)count);
00090 }
00091 
00092 
00093 
00094 template <typename Type, typename Amount> static inline Type
00095 ink_atomic_decrement(volatile Type * mem, Amount count) {
00096   return __sync_fetch_and_sub(mem, (Type)count);
00097 }
00098 
00099 
00100 #if (defined(__arm__) || defined(__mips__)) && (SIZEOF_VOIDP == 4)
00101 extern ink_mutex __global_death;
00102 
00103 template<>
00104 inline int64_t
00105 ink_atomic_swap<int64_t>(pvint64 mem, int64_t value) {
00106   int64_t old;
00107   ink_mutex_acquire(&__global_death);
00108   old = *mem;
00109   *mem = value;
00110   ink_mutex_release(&__global_death);
00111   return old;
00112 }
00113 
00114 template<>
00115 inline bool
00116 ink_atomic_cas<int64_t>(pvint64 mem, int64_t old, int64_t new_value) {
00117   int64_t curr;
00118   ink_mutex_acquire(&__global_death);
00119   curr = *mem;
00120   if(old == curr) *mem = new_value;
00121   ink_mutex_release(&__global_death);
00122   if(old == curr) return 1;
00123   return 0;
00124 }
00125 
00126 template<typename Amount> static inline int64_t
00127 ink_atomic_increment(pvint64 mem, Amount value) {
00128   int64_t curr;
00129   ink_mutex_acquire(&__global_death);
00130   curr = *mem;
00131   *mem = curr + value;
00132   ink_mutex_release(&__global_death);
00133   return curr;
00134 }
00135 
00136 template<typename Amount> static inline int64_t
00137 ink_atomic_decrement(pvint64 mem, Amount value) {
00138   int64_t curr;
00139   ink_mutex_acquire(&__global_death);
00140   curr = *mem;
00141   *mem = curr - value;
00142   ink_mutex_release(&__global_death);
00143   return curr;
00144 }
00145 
00146 template<typename Amount> static inline uint64_t
00147 ink_atomic_increment(pvuint64 mem, Amount value) {
00148   uint64_t curr;
00149   ink_mutex_acquire(&__global_death);
00150   curr = *mem;
00151   *mem = curr + value;
00152   ink_mutex_release(&__global_death);
00153   return curr;
00154 }
00155 
00156 template<typename Amount> static inline uint64_t
00157 ink_atomic_decrement(pvuint64 mem, Amount value) {
00158   uint64_t curr;
00159   ink_mutex_acquire(&__global_death);
00160   curr = *mem;
00161   *mem = curr - value;
00162   ink_mutex_release(&__global_death);
00163   return curr;
00164 }
00165 
00166 #endif 
00167 
00168 
00169 #define INK_WRITE_MEMORY_BARRIER
00170 #define INK_MEMORY_BARRIER
00171 
00172 
00173 #else 
00174 #error Need a compiler / libc that supports atomic operations, e.g. gcc v4.1.2 or later
00175 #endif
00176 
00177 #endif