00001 // 00002 // The Austria library is copyright (c) Gianni Mariani 2004. 00003 // 00004 // Grant Of License. Grants to LICENSEE the non-exclusive right to use the Austria 00005 // library subject to the terms of the LGPL. 00006 // 00007 // A copy of the license is available in this directory or one may be found at this URL: 00008 // http://www.gnu.org/copyleft/lesser.txt 00009 // 00015 #ifndef x_at_gx86_atomic_h_x 00016 #define x_at_gx86_atomic_h_x 1 00017 00018 // Austria namespace 00019 namespace at 00020 { 00021 00022 // ======== AtomicCountType =========================================== 00028 typedef int AtomicCountType; 00029 00030 00031 00032 // ======== AtomicIncrement =========================================== 00041 inline static AtomicCountType AtomicIncrement( 00042 volatile AtomicCountType * io_val 00043 ) { 00044 register int l_a_r_val __asm__ ("eax") = 1; 00045 00046 __asm__ __volatile__ ( 00047 "lock; xaddl %0,%1" 00048 : "+r" (l_a_r_val) 00049 : "m" (*io_val) 00050 : "memory" 00051 ); 00052 00053 return l_a_r_val; 00054 } 00055 00056 // ======== AtomicDecrement =========================================== 00065 inline static AtomicCountType AtomicDecrement( 00066 volatile AtomicCountType * io_val 00067 ) { 00068 register int l_a_r_val __asm__ ("eax") = -1; 00069 00070 __asm__ __volatile__ ( 00071 "lock; xaddl %0,%1" 00072 : "+r" (l_a_r_val) 00073 : "m" (*io_val) 00074 : "memory" 00075 ); 00076 00077 return l_a_r_val; 00078 } 00079 00080 00081 // ======== AtomicBump =========================================== 00091 inline static AtomicCountType AtomicBump( 00092 volatile AtomicCountType * io_val, 00093 AtomicCountType i_add_val 00094 ) { 00095 register int l_a_r_val __asm__ ("eax") = i_add_val; 00096 00097 __asm__ __volatile__ ( 00098 "lock; xaddl %0,%1" 00099 : "+r" (l_a_r_val) 00100 : "m" (*io_val) 00101 : "memory" 00102 ); 00103 00104 return l_a_r_val; 00105 } 00106 00107 00108 // ======== AtomicExchangeablePointer ================================= 00115 typedef void * AtomicExchangeablePointer; 00116 00117 00118 // ======== AtomicExchangeValue ======================================= 00129 inline static AtomicExchangeablePointer AtomicExchange( 00130 volatile AtomicExchangeablePointer * io_mem_loc, 00131 AtomicExchangeablePointer i_val 00132 ) { 00133 00134 #if defined( __x86_64__ ) || defined( __amd64__ ) 00135 00136 __asm__ __volatile__ ( 00137 "xchgq %0,%1" 00138 : "+r" (i_val) 00139 : "m" (*io_mem_loc) 00140 : "memory" 00141 ); 00142 00143 #else 00144 00145 __asm__ __volatile__ ( 00146 "xchgl %0,%1" 00147 : "+r" (i_val) 00148 : "m" (*io_mem_loc) 00149 : "memory" 00150 ); 00151 00152 #endif 00153 00154 return i_val; 00155 00156 } 00157 00158 // ======== AtomicExchangeableValue ================================= 00165 typedef int AtomicExchangeableValue; 00166 00167 00168 // ======== AtomicExchangeValue ======================================= 00179 inline static AtomicExchangeableValue AtomicExchange( 00180 volatile AtomicExchangeableValue * io_mem_loc, 00181 AtomicExchangeableValue i_val 00182 ) { 00183 00184 __asm__ __volatile__ ( 00185 "xchgl %0,%1" 00186 : "+r" (i_val) 00187 : "m" (*io_mem_loc) 00188 : "memory" 00189 ); 00190 00191 return i_val; 00192 00193 } 00194 00195 // ======== AtomicCompareExchange ================================ 00206 inline static AtomicExchangeableValue AtomicCompareExchange( 00207 volatile AtomicExchangeableValue * io_mem_loc, 00208 AtomicExchangeableValue i_val, 00209 AtomicExchangeableValue i_cmp 00210 ) { 00211 register AtomicExchangeableValue l_ret_val; 00212 00213 __asm__ __volatile__ ( 00214 "lock; cmpxchgl %2,%3" 00215 : "=a" (l_ret_val) 00216 : "a" (i_cmp), "q"(i_val), "m" (*io_mem_loc) 00217 : "memory" 00218 ); 00219 00220 return l_ret_val; 00221 } 00222 00223 00224 00225 // ======== AtomicCompareExchange (pointers) ========================= 00237 inline static AtomicExchangeablePointer AtomicCompareExchange( 00238 volatile AtomicExchangeablePointer * io_mem_loc, 00239 AtomicExchangeablePointer i_val, 00240 AtomicExchangeablePointer i_cmp 00241 ) { 00242 register AtomicExchangeablePointer l_ret_val; 00243 00244 #if defined( __x86_64__ ) || defined( __amd64__ ) 00245 00246 __asm__ __volatile__ ( 00247 "lock; cmpxchgq %2,%3" 00248 : "=a" (l_ret_val) 00249 : "a" (i_cmp), "q"(i_val), "m" (*io_mem_loc) 00250 : "memory" 00251 ); 00252 00253 #else 00254 00255 __asm__ __volatile__ ( 00256 "lock; cmpxchgl %2,%3" 00257 : "=a" (l_ret_val) 00258 : "a" (i_cmp), "q"(i_val), "m" (*io_mem_loc) 00259 : "memory" 00260 ); 00261 00262 #endif 00263 00264 return l_ret_val; 00265 } 00266 00267 00268 00269 }; // namespace 00270 00271 #endif // x_at_gx86_atomic_h_x 00272 00273
Generated for Austria by
and
MakeXS at Sun Oct 24 17:35:34 PDT 2004