home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / arch / blackfin / include / asm / atomic.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  3.0 KB  |  145 lines

  1. #ifndef __ARCH_BLACKFIN_ATOMIC__
  2. #define __ARCH_BLACKFIN_ATOMIC__
  3.  
  4. #include <asm/system.h>    /* local_irq_XXX() */
  5.  
  6. /*
  7.  * Atomic operations that C can't guarantee us.  Useful for
  8.  * resource counting etc..
  9.  *
  10.  * Generally we do not concern about SMP BFIN systems, so we don't have
  11.  * to deal with that.
  12.  *
  13.  * Tony Kou (tonyko@lineo.ca)   Lineo Inc.   2001
  14.  */
  15.  
  16. typedef struct {
  17.     int counter;
  18. } atomic_t;
  19. #define ATOMIC_INIT(i)    { (i) }
  20.  
  21. #define atomic_read(v)        ((v)->counter)
  22. #define atomic_set(v, i)    (((v)->counter) = i)
  23.  
  24. static __inline__ void atomic_add(int i, atomic_t * v)
  25. {
  26.     long flags;
  27.  
  28.     local_irq_save(flags);
  29.     v->counter += i;
  30.     local_irq_restore(flags);
  31. }
  32.  
  33. static __inline__ void atomic_sub(int i, atomic_t * v)
  34. {
  35.     long flags;
  36.  
  37.     local_irq_save(flags);
  38.     v->counter -= i;
  39.     local_irq_restore(flags);
  40.  
  41. }
  42.  
  43. static inline int atomic_add_return(int i, atomic_t * v)
  44. {
  45.     int __temp = 0;
  46.     long flags;
  47.  
  48.     local_irq_save(flags);
  49.     v->counter += i;
  50.     __temp = v->counter;
  51.     local_irq_restore(flags);
  52.  
  53.  
  54.     return __temp;
  55. }
  56.  
  57. #define atomic_add_negative(a, v)    (atomic_add_return((a), (v)) < 0)
  58. static inline int atomic_sub_return(int i, atomic_t * v)
  59. {
  60.     int __temp = 0;
  61.     long flags;
  62.  
  63.     local_irq_save(flags);
  64.     v->counter -= i;
  65.     __temp = v->counter;
  66.     local_irq_restore(flags);
  67.  
  68.     return __temp;
  69. }
  70.  
  71. static __inline__ void atomic_inc(volatile atomic_t * v)
  72. {
  73.     long flags;
  74.  
  75.     local_irq_save(flags);
  76.     v->counter++;
  77.     local_irq_restore(flags);
  78. }
  79.  
  80. #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
  81. #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
  82.  
  83. #define atomic_add_unless(v, a, u)                \
  84. ({                                \
  85.     int c, old;                        \
  86.     c = atomic_read(v);                    \
  87.     while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
  88.         c = old;                    \
  89.     c != (u);                        \
  90. })
  91. #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
  92.  
  93. static __inline__ void atomic_dec(volatile atomic_t * v)
  94. {
  95.     long flags;
  96.  
  97.     local_irq_save(flags);
  98.     v->counter--;
  99.     local_irq_restore(flags);
  100. }
  101.  
  102. static __inline__ void atomic_clear_mask(unsigned int mask, atomic_t * v)
  103. {
  104.     long flags;
  105.  
  106.     local_irq_save(flags);
  107.     v->counter &= ~mask;
  108.     local_irq_restore(flags);
  109. }
  110.  
  111. static __inline__ void atomic_set_mask(unsigned int mask, atomic_t * v)
  112. {
  113.     long flags;
  114.  
  115.     local_irq_save(flags);
  116.     v->counter |= mask;
  117.     local_irq_restore(flags);
  118. }
  119.  
  120. /* Atomic operations are already serializing */
  121. #define smp_mb__before_atomic_dec()    barrier()
  122. #define smp_mb__after_atomic_dec() barrier()
  123. #define smp_mb__before_atomic_inc()    barrier()
  124. #define smp_mb__after_atomic_inc() barrier()
  125.  
  126. #define atomic_dec_return(v) atomic_sub_return(1,(v))
  127. #define atomic_inc_return(v) atomic_add_return(1,(v))
  128.  
  129. /*
  130.  * atomic_inc_and_test - increment and test
  131.  * @v: pointer of type atomic_t
  132.  *
  133.  * Atomically increments @v by 1
  134.  * and returns true if the result is zero, or false for all
  135.  * other cases.
  136.  */
  137. #define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
  138.  
  139. #define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
  140. #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
  141.  
  142. #include <asm-generic/atomic.h>
  143.  
  144. #endif                /* __ARCH_BLACKFIN_ATOMIC __ */
  145.