Subversion Repositories Kolibri OS

Rev

Rev 6082 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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.