at v3.3-rc7 2.5 kB view raw
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 */ 15static 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 42static 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 62static 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 75static 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 88static 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 */