Green shading in the line number column means the source is part of the translation unit, red means it is conditionally excluded. Highlighted line numbers link to the translation unit page. Highlighted macros link to the macro page.
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: #ifndef atomic_inc_not_zero 28: #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) 29: #endif 30: 31: /** 32: * atomic_inc_not_zero_hint - increment if not null 33: * @v: pointer of type atomic_t 34: * @hint: probable value of the atomic before the increment 35: * 36: * This version of atomic_inc_not_zero() gives a hint of probable 37: * value of the atomic. This helps processor to not read the memory 38: * before doing the atomic read/modify/write cycle, lowering 39: * number of bus transactions on some arches. 40: * 41: * Returns: 0 if increment was not done, 1 otherwise. 42: */ 43: #ifndef atomic_inc_not_zero_hint 44: static inline int atomic_inc_not_zero_hint(atomic_t *v, int hint) 45: { 46: int val, c = hint; 47: 48: /* sanity test, should be removed by compiler if hint is a constant */ 49: if (!hint) 50: return atomic_inc_not_zero(v); 51: 52: do { 53: val = atomic_cmpxchg(v, c, c + 1); 54: if (val == c) 55: return 1; 56: c = val; 57: } while (c); 58: 59: return 0; 60: } 61: #endif 62: 63: #ifndef atomic_inc_unless_negative 64: static inline int atomic_inc_unless_negative(atomic_t *p) 65: { 66: int v, v1; 67: for (v = 0; v >= 0; v = v1) { 68: v1 = atomic_cmpxchg(p, v, v + 1); 69: if (likely(v1 == v)) 70: return 1; 71: } 72: return 0; 73: } 74: #endif 75: 76: #ifndef atomic_dec_unless_positive 77: static inline int atomic_dec_unless_positive(atomic_t *p) 78: { 79: int v, v1; 80: for (v = 0; v <= 0; v = v1) { 81: v1 = atomic_cmpxchg(p, v, v - 1); 82: if (likely(v1 == v)) 83: return 1; 84: } 85: return 0; 86: } 87: #endif 88: 89: /* 90: * atomic_dec_if_positive - decrement by 1 if old value positive 91: * @v: pointer of type atomic_t 92: * 93: * The function returns the old value of *v minus 1, even if 94: * the atomic variable, v, was not decremented. 95: */ 96: #ifndef atomic_dec_if_positive 97: static inline int atomic_dec_if_positive(atomic_t *v) 98: { 99: int c, old, dec; 100: c = atomic_read(v); 101: for (;;) { 102: dec = c - 1; 103: if (unlikely(dec < 0)) 104: break; 105: old = atomic_cmpxchg((v), c, dec); 106: if (likely(old == c)) 107: break; 108: c = old; 109: } 110: return dec; 111: } 112: #endif 113: 114: #ifndef CONFIG_ARCH_HAS_ATOMIC_OR 115: static inline void atomic_or(int i, atomic_t *v) 116: { 117: int old; 118: int new; 119: 120: do { 121: old = atomic_read(v); 122: new = old | i; 123: } while (atomic_cmpxchg(v, old, new) != old); 124: } 125: #endif /* #ifndef CONFIG_ARCH_HAS_ATOMIC_OR */ 126: 127: #include <asm-generic/atomic-long.h> 128: #ifdef CONFIG_GENERIC_ATOMIC64 129: #include <asm-generic/atomic64.h> 130: #endif 131: #endif /* _LINUX_ATOMIC_H */ 132: