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