at v4.13 246 lines 7.0 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_FETCH_OP(op, mo) \ 116static inline long \ 117atomic_long_fetch_##op##mo(long i, atomic_long_t *l) \ 118{ \ 119 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ 120 \ 121 return (long)ATOMIC_LONG_PFX(_fetch_##op##mo)(i, v); \ 122} 123 124ATOMIC_LONG_FETCH_OP(add, ) 125ATOMIC_LONG_FETCH_OP(add, _relaxed) 126ATOMIC_LONG_FETCH_OP(add, _acquire) 127ATOMIC_LONG_FETCH_OP(add, _release) 128ATOMIC_LONG_FETCH_OP(sub, ) 129ATOMIC_LONG_FETCH_OP(sub, _relaxed) 130ATOMIC_LONG_FETCH_OP(sub, _acquire) 131ATOMIC_LONG_FETCH_OP(sub, _release) 132ATOMIC_LONG_FETCH_OP(and, ) 133ATOMIC_LONG_FETCH_OP(and, _relaxed) 134ATOMIC_LONG_FETCH_OP(and, _acquire) 135ATOMIC_LONG_FETCH_OP(and, _release) 136ATOMIC_LONG_FETCH_OP(andnot, ) 137ATOMIC_LONG_FETCH_OP(andnot, _relaxed) 138ATOMIC_LONG_FETCH_OP(andnot, _acquire) 139ATOMIC_LONG_FETCH_OP(andnot, _release) 140ATOMIC_LONG_FETCH_OP(or, ) 141ATOMIC_LONG_FETCH_OP(or, _relaxed) 142ATOMIC_LONG_FETCH_OP(or, _acquire) 143ATOMIC_LONG_FETCH_OP(or, _release) 144ATOMIC_LONG_FETCH_OP(xor, ) 145ATOMIC_LONG_FETCH_OP(xor, _relaxed) 146ATOMIC_LONG_FETCH_OP(xor, _acquire) 147ATOMIC_LONG_FETCH_OP(xor, _release) 148 149#undef ATOMIC_LONG_FETCH_OP 150 151#define ATOMIC_LONG_FETCH_INC_DEC_OP(op, mo) \ 152static inline long \ 153atomic_long_fetch_##op##mo(atomic_long_t *l) \ 154{ \ 155 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ 156 \ 157 return (long)ATOMIC_LONG_PFX(_fetch_##op##mo)(v); \ 158} 159 160ATOMIC_LONG_FETCH_INC_DEC_OP(inc,) 161ATOMIC_LONG_FETCH_INC_DEC_OP(inc, _relaxed) 162ATOMIC_LONG_FETCH_INC_DEC_OP(inc, _acquire) 163ATOMIC_LONG_FETCH_INC_DEC_OP(inc, _release) 164ATOMIC_LONG_FETCH_INC_DEC_OP(dec,) 165ATOMIC_LONG_FETCH_INC_DEC_OP(dec, _relaxed) 166ATOMIC_LONG_FETCH_INC_DEC_OP(dec, _acquire) 167ATOMIC_LONG_FETCH_INC_DEC_OP(dec, _release) 168 169#undef ATOMIC_LONG_FETCH_INC_DEC_OP 170 171#define ATOMIC_LONG_OP(op) \ 172static __always_inline void \ 173atomic_long_##op(long i, atomic_long_t *l) \ 174{ \ 175 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ 176 \ 177 ATOMIC_LONG_PFX(_##op)(i, v); \ 178} 179 180ATOMIC_LONG_OP(add) 181ATOMIC_LONG_OP(sub) 182ATOMIC_LONG_OP(and) 183ATOMIC_LONG_OP(andnot) 184ATOMIC_LONG_OP(or) 185ATOMIC_LONG_OP(xor) 186 187#undef ATOMIC_LONG_OP 188 189static inline int atomic_long_sub_and_test(long i, atomic_long_t *l) 190{ 191 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; 192 193 return ATOMIC_LONG_PFX(_sub_and_test)(i, v); 194} 195 196static inline int atomic_long_dec_and_test(atomic_long_t *l) 197{ 198 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; 199 200 return ATOMIC_LONG_PFX(_dec_and_test)(v); 201} 202 203static inline int atomic_long_inc_and_test(atomic_long_t *l) 204{ 205 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; 206 207 return ATOMIC_LONG_PFX(_inc_and_test)(v); 208} 209 210static inline int atomic_long_add_negative(long i, atomic_long_t *l) 211{ 212 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; 213 214 return ATOMIC_LONG_PFX(_add_negative)(i, v); 215} 216 217#define ATOMIC_LONG_INC_DEC_OP(op, mo) \ 218static inline long \ 219atomic_long_##op##_return##mo(atomic_long_t *l) \ 220{ \ 221 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \ 222 \ 223 return (long)ATOMIC_LONG_PFX(_##op##_return##mo)(v); \ 224} 225ATOMIC_LONG_INC_DEC_OP(inc,) 226ATOMIC_LONG_INC_DEC_OP(inc, _relaxed) 227ATOMIC_LONG_INC_DEC_OP(inc, _acquire) 228ATOMIC_LONG_INC_DEC_OP(inc, _release) 229ATOMIC_LONG_INC_DEC_OP(dec,) 230ATOMIC_LONG_INC_DEC_OP(dec, _relaxed) 231ATOMIC_LONG_INC_DEC_OP(dec, _acquire) 232ATOMIC_LONG_INC_DEC_OP(dec, _release) 233 234#undef ATOMIC_LONG_INC_DEC_OP 235 236static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u) 237{ 238 ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; 239 240 return (long)ATOMIC_LONG_PFX(_add_unless)(v, a, u); 241} 242 243#define atomic_long_inc_not_zero(l) \ 244 ATOMIC_LONG_PFX(_inc_not_zero)((ATOMIC_LONG_PFX(_t) *)(l)) 245 246#endif /* _ASM_GENERIC_ATOMIC_LONG_H */