Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/include/atomic.h

    r340ba25c r9d58539  
    11/*
    22 * Copyright (c) 2001-2004 Jakub Jermar
    3  * Copyright (c) 2012      Adam Hraska
    43 * All rights reserved.
    54 *
     
    141140}
    142141
    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_cas
    216 
    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 #else
    229 /* Check if arch/atomic.h does not accidentally include /atomic.h .*/
    230 #error Architecture specific cpu local atomics already defined! Check your includes.
    231 #endif
    232 
    233 
    234 #ifndef local_atomic_exchange
    235 /*
    236  * Issuing a xchg instruction always implies lock prefix semantics.
    237  * Therefore, it is cheaper to use a cmpxchg without a lock prefix
    238  * 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 #else
    256 /* Check if arch/atomic.h does not accidentally include /atomic.h .*/
    257 #error Architecture specific cpu local atomics already defined! Check your includes.
    258 #endif
    259 
    260 
    261142#endif
    262143
Note: See TracChangeset for help on using the changeset viewer.