#ifndef __BP_ATOMIC_H #define __BP_ATOMIC_H #include_next /* atomic_cmpxchg_relaxed */ #ifndef atomic_cmpxchg_relaxed #define atomic_cmpxchg_relaxed atomic_cmpxchg #define atomic_cmpxchg_acquire atomic_cmpxchg #define atomic_cmpxchg_release atomic_cmpxchg #else /* atomic_cmpxchg_relaxed */ #ifndef atomic_cmpxchg_acquire #define atomic_cmpxchg_acquire(...) \ __atomic_op_acquire(atomic_cmpxchg, __VA_ARGS__) #endif #ifndef atomic_cmpxchg_release #define atomic_cmpxchg_release(...) \ __atomic_op_release(atomic_cmpxchg, __VA_ARGS__) #endif #ifndef atomic_cmpxchg #define atomic_cmpxchg(...) \ __atomic_op_fence(atomic_cmpxchg, __VA_ARGS__) #endif #endif /* atomic_cmpxchg_relaxed */ /* these were introduced together, so just a single check is enough */ #ifndef atomic_try_cmpxchg_acquire #ifndef atomic_try_cmpxchg #define __atomic_try_cmpxchg(type, _p, _po, _n) \ ({ \ typeof(_po) __po = (_po); \ typeof(*(_po)) __r, __o = *__po; \ __r = atomic_cmpxchg##type((_p), __o, (_n)); \ if (unlikely(__r != __o)) \ *__po = __r; \ likely(__r == __o); \ }) #define atomic_try_cmpxchg(_p, _po, _n) __atomic_try_cmpxchg(, _p, _po, _n) #define atomic_try_cmpxchg_relaxed(_p, _po, _n) __atomic_try_cmpxchg(_relaxed, _p, _po, _n) #define atomic_try_cmpxchg_acquire(_p, _po, _n) __atomic_try_cmpxchg(_acquire, _p, _po, _n) #define atomic_try_cmpxchg_release(_p, _po, _n) __atomic_try_cmpxchg(_release, _p, _po, _n) #else /* atomic_try_cmpxchg */ #define atomic_try_cmpxchg_relaxed atomic_try_cmpxchg #define atomic_try_cmpxchg_acquire atomic_try_cmpxchg #define atomic_try_cmpxchg_release atomic_try_cmpxchg #endif /* atomic_try_cmpxchg */ #endif /* atomic_try_cmpxchg_acquire */ #if LINUX_VERSION_IS_LESS(3,7,0) /* * atomic_dec_if_positive - decrement by 1 if old value positive * @v: pointer of type atomic_t * * The function returns the old value of *v minus 1, even if * the atomic variable, v, was not decremented. */ static inline int atomic_dec_if_positive(atomic_t *v) { int c, old, dec; c = atomic_read(v); for (;;) { dec = c - 1; if (unlikely(dec < 0)) break; old = atomic_cmpxchg((v), c, dec); if (likely(old == c)) break; c = old; } return dec; } #endif #endif /* __BP_ATOMIC_H */