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