at v4.7-rc7 190 lines 5.2 kB view raw
1#ifndef _ASM_GENERIC_ATOMIC_LONG_H 2#define _ASM_GENERIC_ATOMIC_LONG_H 3/* 4 * Copyright (C) 2005 Silicon Graphics, Inc. 5 * Christoph Lameter 6 * 7 * Allows to provide arch independent atomic definitions without the need to 8 * edit all arch specific atomic.h files. 9 */ 10 11#include <asm/types.h> 12 13/* 14 * Suppport for atomic_long_t 15 * 16 * Casts for parameters are avoided for existing atomic functions in order to 17 * avoid issues with cast-as-lval under gcc 4.x and other limitations that the 18 * macros of a platform may have. 19 */ 20 21#if BITS_PER_LONG == 64 22 23typedef atomic64_t atomic_long_t; 24 25#define ATOMIC_LONG_INIT(i) ATOMIC64_INIT(i) 26#define ATOMIC_LONG_PFX(x) atomic64 ## x 27 28#else 29 30typedef atomic_t atomic_long_t; 31 32#define ATOMIC_LONG_INIT(i) ATOMIC_INIT(i) 33#define ATOMIC_LONG_PFX(x) atomic ## x 34 35#endif 36 37#define ATOMIC_LONG_READ_OP(mo) \ 38static inline long atomic_long_read##mo(const atomic_long_t *l) \ 39{ \ 40 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ 41 \ 42 return (long)ATOMIC_LONG_PFX(_read##mo)(v); \ 43} 44ATOMIC_LONG_READ_OP() 45ATOMIC_LONG_READ_OP(_acquire) 46 47#undef ATOMIC_LONG_READ_OP 48 49#define ATOMIC_LONG_SET_OP(mo) \ 50static inline void atomic_long_set##mo(atomic_long_t *l, long i) \ 51{ \ 52 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ 53 \ 54 ATOMIC_LONG_PFX(_set##mo)(v, i); \ 55} 56ATOMIC_LONG_SET_OP() 57ATOMIC_LONG_SET_OP(_release) 58 59#undef ATOMIC_LONG_SET_OP 60 61#define ATOMIC_LONG_ADD_SUB_OP(op, mo) \ 62static inline long \ 63atomic_long_##op##_return##mo(long i, atomic_long_t *l) \ 64{ \ 65 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ 66 \ 67 return (long)ATOMIC_LONG_PFX(_##op##_return##mo)(i, v); \ 68} 69ATOMIC_LONG_ADD_SUB_OP(add,) 70ATOMIC_LONG_ADD_SUB_OP(add, _relaxed) 71ATOMIC_LONG_ADD_SUB_OP(add, _acquire) 72ATOMIC_LONG_ADD_SUB_OP(add, _release) 73ATOMIC_LONG_ADD_SUB_OP(sub,) 74ATOMIC_LONG_ADD_SUB_OP(sub, _relaxed) 75ATOMIC_LONG_ADD_SUB_OP(sub, _acquire) 76ATOMIC_LONG_ADD_SUB_OP(sub, _release) 77 78#undef ATOMIC_LONG_ADD_SUB_OP 79 80#define atomic_long_cmpxchg_relaxed(l, old, new) \ 81 (ATOMIC_LONG_PFX(_cmpxchg_relaxed)((ATOMIC_LONG_PFX(_t) *)(l), \ 82 (old), (new))) 83#define atomic_long_cmpxchg_acquire(l, old, new) \ 84 (ATOMIC_LONG_PFX(_cmpxchg_acquire)((ATOMIC_LONG_PFX(_t) *)(l), \ 85 (old), (new))) 86#define atomic_long_cmpxchg_release(l, old, new) \ 87 (ATOMIC_LONG_PFX(_cmpxchg_release)((ATOMIC_LONG_PFX(_t) *)(l), \ 88 (old), (new))) 89#define atomic_long_cmpxchg(l, old, new) \ 90 (ATOMIC_LONG_PFX(_cmpxchg)((ATOMIC_LONG_PFX(_t) *)(l), (old), (new))) 91 92#define atomic_long_xchg_relaxed(v, new) \ 93 (ATOMIC_LONG_PFX(_xchg_relaxed)((ATOMIC_LONG_PFX(_t) *)(v), (new))) 94#define atomic_long_xchg_acquire(v, new) \ 95 (ATOMIC_LONG_PFX(_xchg_acquire)((ATOMIC_LONG_PFX(_t) *)(v), (new))) 96#define atomic_long_xchg_release(v, new) \ 97 (ATOMIC_LONG_PFX(_xchg_release)((ATOMIC_LONG_PFX(_t) *)(v), (new))) 98#define atomic_long_xchg(v, new) \ 99 (ATOMIC_LONG_PFX(_xchg)((ATOMIC_LONG_PFX(_t) *)(v), (new))) 100 101static __always_inline void atomic_long_inc(atomic_long_t *l) 102{ 103 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; 104 105 ATOMIC_LONG_PFX(_inc)(v); 106} 107 108static __always_inline void atomic_long_dec(atomic_long_t *l) 109{ 110 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; 111 112 ATOMIC_LONG_PFX(_dec)(v); 113} 114 115#define ATOMIC_LONG_OP(op) \ 116static __always_inline void \ 117atomic_long_##op(long i, atomic_long_t *l) \ 118{ \ 119 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ 120 \ 121 ATOMIC_LONG_PFX(_##op)(i, v); \ 122} 123 124ATOMIC_LONG_OP(add) 125ATOMIC_LONG_OP(sub) 126ATOMIC_LONG_OP(and) 127ATOMIC_LONG_OP(or) 128ATOMIC_LONG_OP(xor) 129ATOMIC_LONG_OP(andnot) 130 131#undef ATOMIC_LONG_OP 132 133static inline int atomic_long_sub_and_test(long i, atomic_long_t *l) 134{ 135 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; 136 137 return ATOMIC_LONG_PFX(_sub_and_test)(i, v); 138} 139 140static inline int atomic_long_dec_and_test(atomic_long_t *l) 141{ 142 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; 143 144 return ATOMIC_LONG_PFX(_dec_and_test)(v); 145} 146 147static inline int atomic_long_inc_and_test(atomic_long_t *l) 148{ 149 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; 150 151 return ATOMIC_LONG_PFX(_inc_and_test)(v); 152} 153 154static inline int atomic_long_add_negative(long i, atomic_long_t *l) 155{ 156 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; 157 158 return ATOMIC_LONG_PFX(_add_negative)(i, v); 159} 160 161#define ATOMIC_LONG_INC_DEC_OP(op, mo) \ 162static inline long \ 163atomic_long_##op##_return##mo(atomic_long_t *l) \ 164{ \ 165 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ 166 \ 167 return (long)ATOMIC_LONG_PFX(_##op##_return##mo)(v); \ 168} 169ATOMIC_LONG_INC_DEC_OP(inc,) 170ATOMIC_LONG_INC_DEC_OP(inc, _relaxed) 171ATOMIC_LONG_INC_DEC_OP(inc, _acquire) 172ATOMIC_LONG_INC_DEC_OP(inc, _release) 173ATOMIC_LONG_INC_DEC_OP(dec,) 174ATOMIC_LONG_INC_DEC_OP(dec, _relaxed) 175ATOMIC_LONG_INC_DEC_OP(dec, _acquire) 176ATOMIC_LONG_INC_DEC_OP(dec, _release) 177 178#undef ATOMIC_LONG_INC_DEC_OP 179 180static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u) 181{ 182 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; 183 184 return (long)ATOMIC_LONG_PFX(_add_unless)(v, a, u); 185} 186 187#define atomic_long_inc_not_zero(l) \ 188 ATOMIC_LONG_PFX(_inc_not_zero)((ATOMIC_LONG_PFX(_t) *)(l)) 189 190#endif /* _ASM_GENERIC_ATOMIC_LONG_H */