Changeset 6831475 in mainline for kernel/arch/amd64/include/atomic.h
- Timestamp:
- 2012-11-19T21:13:01Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 82719589
- Parents:
- 657ddbd
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/include/atomic.h
r657ddbd r6831475 141 141 142 142 143 #define _atomic_cas_impl(pptr, exp_val, new_val, old_val, prefix) \ 144 ({ \ 145 switch (sizeof(typeof(*(pptr)))) { \ 146 case 1: \ 147 asm volatile ( \ 148 prefix " cmpxchgb %[newval], %[ptr]\n" \ 149 : /* Output operands. */ \ 150 /* Old/current value is returned in eax. */ \ 151 [oldval] "=a" (old_val), \ 152 /* (*ptr) will be read and written to, hence "+" */ \ 153 [ptr] "+m" (*pptr) \ 154 : /* Input operands. */ \ 155 /* Expected value must be in eax. */ \ 156 [expval] "a" (exp_val), \ 157 /* The new value may be in any register. */ \ 158 [newval] "r" (new_val) \ 159 : "memory" \ 160 ); \ 161 break; \ 162 case 2: \ 163 asm volatile ( \ 164 prefix " cmpxchgw %[newval], %[ptr]\n" \ 165 : /* Output operands. */ \ 166 /* Old/current value is returned in eax. */ \ 167 [oldval] "=a" (old_val), \ 168 /* (*ptr) will be read and written to, hence "+" */ \ 169 [ptr] "+m" (*pptr) \ 170 : /* Input operands. */ \ 171 /* Expected value must be in eax. */ \ 172 [expval] "a" (exp_val), \ 173 /* The new value may be in any register. */ \ 174 [newval] "r" (new_val) \ 175 : "memory" \ 176 ); \ 177 break; \ 178 case 4: \ 179 asm volatile ( \ 180 prefix " cmpxchgl %[newval], %[ptr]\n" \ 181 : /* Output operands. */ \ 182 /* Old/current value is returned in eax. */ \ 183 [oldval] "=a" (old_val), \ 184 /* (*ptr) will be read and written to, hence "+" */ \ 185 [ptr] "+m" (*pptr) \ 186 : /* Input operands. */ \ 187 /* Expected value must be in eax. */ \ 188 [expval] "a" (exp_val), \ 189 /* The new value may be in any register. */ \ 190 [newval] "r" (new_val) \ 191 : "memory" \ 192 ); \ 193 break; \ 194 case 8: \ 195 asm volatile ( \ 196 prefix " cmpxchgq %[newval], %[ptr]\n" \ 197 : /* Output operands. */ \ 198 /* Old/current value is returned in eax. */ \ 199 [oldval] "=a" (old_val), \ 200 /* (*ptr) will be read and written to, hence "+" */ \ 201 [ptr] "+m" (*pptr) \ 202 : /* Input operands. */ \ 203 /* Expected value must be in eax. */ \ 204 [expval] "a" (exp_val), \ 205 /* The new value may be in any register. */ \ 206 [newval] "r" (new_val) \ 207 : "memory" \ 208 ); \ 209 break; \ 210 } \ 211 }) 212 213 214 #ifndef local_atomic_cas 215 216 #define local_atomic_cas(pptr, exp_val, new_val) \ 217 ({ \ 218 typeof(*(pptr)) old_val; \ 219 _atomic_cas_impl(pptr, exp_val, new_val, old_val, ""); \ 220 \ 221 old_val; \ 222 }) 223 224 #else 225 /* Check if arch/atomic.h does not accidentally include /atomic.h .*/ 226 #error Architecture specific cpu local atomics already defined! Check your includes. 143 227 #endif 144 228 229 230 #ifndef local_atomic_exchange 231 /* 232 * Issuing a xchg instruction always implies lock prefix semantics. 233 * Therefore, it is cheaper to use a cmpxchg without a lock prefix 234 * in a loop. 235 */ 236 #define local_atomic_exchange(pptr, new_val) \ 237 ({ \ 238 typeof(*(pptr)) exp_val; \ 239 typeof(*(pptr)) old_val; \ 240 \ 241 do { \ 242 exp_val = *pptr; \ 243 old_val = local_atomic_cas(pptr, exp_val, new_val); \ 244 } while (old_val != exp_val); \ 245 \ 246 old_val; \ 247 }) 248 249 #else 250 /* Check if arch/atomic.h does not accidentally include /atomic.h .*/ 251 #error Architecture specific cpu local atomics already defined! Check your includes. 252 #endif 253 254 255 #endif 256 145 257 /** @} 146 258 */
Note:
See TracChangeset
for help on using the changeset viewer.