1 /* Atomic operations usable in machine independent code */ 2 #ifndef _LINUX_ATOMIC_H 3 #define _LINUX_ATOMIC_H 4 #include <asm/atomic.h> 5 6 /** 7 * atomic_add_unless - add unless the number is already a given value 8 * @v: pointer of type atomic_t 9 * @a: the amount to add to v... 10 * @u: ...unless v is equal to u. 11 * 12 * Atomically adds @a to @v, so long as @v was not already @u. 13 * Returns non-zero if @v was not @u, and zero otherwise. 14 */ 15 static inline int atomic_add_unless(atomic_t *v, int a, int u) 16 { 17 return __atomic_add_unless(v, a, u) != u; 18 } 19 20 /** 21 * atomic_inc_not_zero - increment unless the number is zero 22 * @v: pointer of type atomic_t 23 * 24 * Atomically increments @v by 1, so long as @v is non-zero. 25 * Returns non-zero if @v was non-zero, and zero otherwise. 26 */ 27 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) 28 29 /** 30 * atomic_inc_not_zero_hint - increment if not null 31 * @v: pointer of type atomic_t 32 * @hint: probable value of the atomic before the increment 33 * 34 * This version of atomic_inc_not_zero() gives a hint of probable 35 * value of the atomic. This helps processor to not read the memory 36 * before doing the atomic read/modify/write cycle, lowering 37 * number of bus transactions on some arches. 38 * 39 * Returns: 0 if increment was not done, 1 otherwise. 40 */ 41 #ifndef atomic_inc_not_zero_hint 42 static inline int atomic_inc_not_zero_hint(atomic_t *v, int hint) 43 { 44 int val, c = hint; 45 46 /* sanity test, should be removed by compiler if hint is a constant */ 47 if (!hint) 48 return atomic_inc_not_zero(v); 49 50 do { 51 val = atomic_cmpxchg(v, c, c + 1); 52 if (val == c) 53 return 1; 54 c = val; 55 } while (c); 56 57 return 0; 58 } 59 #endif 60 61 #ifndef atomic_inc_unless_negative 62 static inline int atomic_inc_unless_negative(atomic_t *p) 63 { 64 int v, v1; 65 for (v = 0; v >= 0; v = v1) { 66 v1 = atomic_cmpxchg(p, v, v + 1); 67 if (likely(v1 == v)) 68 return 1; 69 } 70 return 0; 71 } 72 #endif 73 74 #ifndef atomic_dec_unless_positive 75 static inline int atomic_dec_unless_positive(atomic_t *p) 76 { 77 int v, v1; 78 for (v = 0; v <= 0; v = v1) { 79 v1 = atomic_cmpxchg(p, v, v - 1); 80 if (likely(v1 == v)) 81 return 1; 82 } 83 return 0; 84 } 85 #endif 86 87 #ifndef CONFIG_ARCH_HAS_ATOMIC_OR 88 static inline void atomic_or(int i, atomic_t *v) 89 { 90 int old; 91 int new; 92 93 do { 94 old = atomic_read(v); 95 new = old | i; 96 } while (atomic_cmpxchg(v, old, new) != old); 97 } 98 #endif /* #ifndef CONFIG_ARCH_HAS_ATOMIC_OR */ 99 100 #include <asm-generic/atomic-long.h> 101 #ifdef CONFIG_GENERIC_ATOMIC64 102 #include <asm-generic/atomic64.h> 103 #endif 104 #endif /* _LINUX_ATOMIC_H */ 105