Ignore:
Timestamp:
2014-10-09T15:03:55Z (10 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e367939c
Parents:
21799398 (diff), 207e8880 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~adam-hraska+lp/helenos/rcu/.

Only merge from the feature branch and resolve all conflicts.

File:
1 edited

Legend:

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

    r21799398 rb1c57a8  
    11/*
    22 * Copyright (c) 2001-2004 Jakub Jermar
     3 * Copyright (c) 2012      Adam Hraska
    34 * All rights reserved.
    45 *
     
    140141}
    141142
     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.
    142231#endif
    143232
     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
     261#endif
     262
    144263/** @}
    145264 */
Note: See TracChangeset for help on using the changeset viewer.