Changes in kernel/arch/amd64/include/atomic.h [340ba25c:9d58539] in mainline
- File:
-
- 1 edited
-
kernel/arch/amd64/include/atomic.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/include/atomic.h
r340ba25c r9d58539 1 1 /* 2 2 * Copyright (c) 2001-2004 Jakub Jermar 3 * Copyright (c) 2012 Adam Hraska4 3 * All rights reserved. 5 4 * … … 141 140 } 142 141 143 144 #define _atomic_cas_impl(pptr, exp_val, new_val, old_val, prefix) \145 ({ \146 switch (sizeof(typeof(*(pptr)))) { \147 case 1: \148 asm volatile ( \149 prefix " cmpxchgb %[newval], %[ptr]\n" \150 : /* Output operands. */ \151 /* Old/current value is returned in eax. */ \152 [oldval] "=a" (old_val), \153 /* (*ptr) will be read and written to, hence "+" */ \154 [ptr] "+m" (*pptr) \155 : /* Input operands. */ \156 /* Expected value must be in eax. */ \157 [expval] "a" (exp_val), \158 /* The new value may be in any register. */ \159 [newval] "r" (new_val) \160 : "memory" \161 ); \162 break; \163 case 2: \164 asm volatile ( \165 prefix " cmpxchgw %[newval], %[ptr]\n" \166 : /* Output operands. */ \167 /* Old/current value is returned in eax. */ \168 [oldval] "=a" (old_val), \169 /* (*ptr) will be read and written to, hence "+" */ \170 [ptr] "+m" (*pptr) \171 : /* Input operands. */ \172 /* Expected value must be in eax. */ \173 [expval] "a" (exp_val), \174 /* The new value may be in any register. */ \175 [newval] "r" (new_val) \176 : "memory" \177 ); \178 break; \179 case 4: \180 asm volatile ( \181 prefix " cmpxchgl %[newval], %[ptr]\n" \182 : /* Output operands. */ \183 /* Old/current value is returned in eax. */ \184 [oldval] "=a" (old_val), \185 /* (*ptr) will be read and written to, hence "+" */ \186 [ptr] "+m" (*pptr) \187 : /* Input operands. */ \188 /* Expected value must be in eax. */ \189 [expval] "a" (exp_val), \190 /* The new value may be in any register. */ \191 [newval] "r" (new_val) \192 : "memory" \193 ); \194 break; \195 case 8: \196 asm volatile ( \197 prefix " cmpxchgq %[newval], %[ptr]\n" \198 : /* Output operands. */ \199 /* Old/current value is returned in eax. */ \200 [oldval] "=a" (old_val), \201 /* (*ptr) will be read and written to, hence "+" */ \202 [ptr] "+m" (*pptr) \203 : /* Input operands. */ \204 /* Expected value must be in eax. */ \205 [expval] "a" (exp_val), \206 /* The new value may be in any register. */ \207 [newval] "r" (new_val) \208 : "memory" \209 ); \210 break; \211 } \212 })213 214 215 #ifndef local_atomic_cas216 217 #define local_atomic_cas(pptr, exp_val, new_val) \218 ({ \219 /* Use proper types and avoid name clashes */ \220 typeof(*(pptr)) _old_val_cas; \221 typeof(*(pptr)) _exp_val_cas = exp_val; \222 typeof(*(pptr)) _new_val_cas = new_val; \223 _atomic_cas_impl(pptr, _exp_val_cas, _new_val_cas, _old_val_cas, ""); \224 \225 _old_val_cas; \226 })227 228 #else229 /* Check if arch/atomic.h does not accidentally include /atomic.h .*/230 #error Architecture specific cpu local atomics already defined! Check your includes.231 #endif232 233 234 #ifndef local_atomic_exchange235 /*236 * Issuing a xchg instruction always implies lock prefix semantics.237 * Therefore, it is cheaper to use a cmpxchg without a lock prefix238 * in a loop.239 */240 #define local_atomic_exchange(pptr, new_val) \241 ({ \242 /* Use proper types and avoid name clashes */ \243 typeof(*(pptr)) _exp_val_x; \244 typeof(*(pptr)) _old_val_x; \245 typeof(*(pptr)) _new_val_x = new_val; \246 \247 do { \248 _exp_val_x = *pptr; \249 _old_val_x = local_atomic_cas(pptr, _exp_val_x, _new_val_x); \250 } while (_old_val_x != _exp_val_x); \251 \252 _old_val_x; \253 })254 255 #else256 /* Check if arch/atomic.h does not accidentally include /atomic.h .*/257 #error Architecture specific cpu local atomics already defined! Check your includes.258 #endif259 260 261 142 #endif 262 143
Note:
See TracChangeset
for help on using the changeset viewer.
