File: /Users/paulross/dev/linux/linux-3.13/include/linux/atomic.h

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: