linux-old/include/asm-i386/atomic.h
<<
>>
Prefs
   1#ifndef __ARCH_I386_ATOMIC__
   2#define __ARCH_I386_ATOMIC__
   3
   4#include <linux/config.h>
   5
   6/*
   7 * Atomic operations that C can't guarantee us.  Useful for
   8 * resource counting etc..
   9 */
  10
  11#ifdef CONFIG_SMP
  12#define LOCK "lock ; "
  13#else
  14#define LOCK ""
  15#endif
  16
  17/*
  18 * Make sure gcc doesn't try to be clever and move things around
  19 * on us. We need to use _exactly_ the address the user gave us,
  20 * not some alias that contains the same information.
  21 */
  22typedef struct { volatile int counter; } atomic_t;
  23
  24#define ATOMIC_INIT(i)  { (i) }
  25
  26/**
  27 * atomic_read - read atomic variable
  28 * @v: pointer of type atomic_t
  29 * 
  30 * Atomically reads the value of @v.  Note that the guaranteed
  31 * useful range of an atomic_t is only 24 bits.
  32 */ 
  33#define atomic_read(v)          ((v)->counter)
  34
  35/**
  36 * atomic_set - set atomic variable
  37 * @v: pointer of type atomic_t
  38 * @i: required value
  39 * 
  40 * Atomically sets the value of @v to @i.  Note that the guaranteed
  41 * useful range of an atomic_t is only 24 bits.
  42 */ 
  43#define atomic_set(v,i)         (((v)->counter) = (i))
  44
  45/**
  46 * atomic_add - add integer to atomic variable
  47 * @i: integer value to add
  48 * @v: pointer of type atomic_t
  49 * 
  50 * Atomically adds @i to @v.  Note that the guaranteed useful range
  51 * of an atomic_t is only 24 bits.
  52 */
  53static __inline__ void atomic_add(int i, atomic_t *v)
  54{
  55        __asm__ __volatile__(
  56                LOCK "addl %1,%0"
  57                :"=m" (v->counter)
  58                :"ir" (i), "m" (v->counter));
  59}
  60
  61/**
  62 * atomic_sub - subtract the atomic variable
  63 * @i: integer value to subtract
  64 * @v: pointer of type atomic_t
  65 * 
  66 * Atomically subtracts @i from @v.  Note that the guaranteed
  67 * useful range of an atomic_t is only 24 bits.
  68 */
  69static __inline__ void atomic_sub(int i, atomic_t *v)
  70{
  71        __asm__ __volatile__(
  72                LOCK "subl %1,%0"
  73                :"=m" (v->counter)
  74                :"ir" (i), "m" (v->counter));
  75}
  76
  77/**
  78 * atomic_sub_and_test - subtract value from variable and test result
  79 * @i: integer value to subtract
  80 * @v: pointer of type atomic_t
  81 * 
  82 * Atomically subtracts @i from @v and returns
  83 * true if the result is zero, or false for all
  84 * other cases.  Note that the guaranteed
  85 * useful range of an atomic_t is only 24 bits.
  86 */
  87static __inline__ int atomic_sub_and_test(int i, atomic_t *v)
  88{
  89        unsigned char c;
  90
  91        __asm__ __volatile__(
  92                LOCK "subl %2,%0; sete %1"
  93                :"=m" (v->counter), "=qm" (c)
  94                :"ir" (i), "m" (v->counter) : "memory");
  95        return c;
  96}
  97
  98/**
  99 * atomic_inc - increment atomic variable
 100 * @v: pointer of type atomic_t
 101 * 
 102 * Atomically increments @v by 1.  Note that the guaranteed
 103 * useful range of an atomic_t is only 24 bits.
 104 */ 
 105static __inline__ void atomic_inc(atomic_t *v)
 106{
 107        __asm__ __volatile__(
 108                LOCK "incl %0"
 109                :"=m" (v->counter)
 110                :"m" (v->counter));
 111}
 112
 113/**
 114 * atomic_dec - decrement atomic variable
 115 * @v: pointer of type atomic_t
 116 * 
 117 * Atomically decrements @v by 1.  Note that the guaranteed
 118 * useful range of an atomic_t is only 24 bits.
 119 */ 
 120static __inline__ void atomic_dec(atomic_t *v)
 121{
 122        __asm__ __volatile__(
 123                LOCK "decl %0"
 124                :"=m" (v->counter)
 125                :"m" (v->counter));
 126}
 127
 128/**
 129 * atomic_dec_and_test - decrement and test
 130 * @v: pointer of type atomic_t
 131 * 
 132 * Atomically decrements @v by 1 and
 133 * returns true if the result is 0, or false for all other
 134 * cases.  Note that the guaranteed
 135 * useful range of an atomic_t is only 24 bits.
 136 */ 
 137static __inline__ int atomic_dec_and_test(atomic_t *v)
 138{
 139        unsigned char c;
 140
 141        __asm__ __volatile__(
 142                LOCK "decl %0; sete %1"
 143                :"=m" (v->counter), "=qm" (c)
 144                :"m" (v->counter) : "memory");
 145        return c != 0;
 146}
 147
 148/**
 149 * atomic_inc_and_test - increment and test 
 150 * @v: pointer of type atomic_t
 151 * 
 152 * Atomically increments @v by 1
 153 * and returns true if the result is zero, or false for all
 154 * other cases.  Note that the guaranteed
 155 * useful range of an atomic_t is only 24 bits.
 156 */ 
 157static __inline__ int atomic_inc_and_test(atomic_t *v)
 158{
 159        unsigned char c;
 160
 161        __asm__ __volatile__(
 162                LOCK "incl %0; sete %1"
 163                :"=m" (v->counter), "=qm" (c)
 164                :"m" (v->counter) : "memory");
 165        return c != 0;
 166}
 167
 168/**
 169 * atomic_add_negative - add and test if negative
 170 * @v: pointer of type atomic_t
 171 * @i: integer value to add
 172 * 
 173 * Atomically adds @i to @v and returns true
 174 * if the result is negative, or false when
 175 * result is greater than or equal to zero.  Note that the guaranteed
 176 * useful range of an atomic_t is only 24 bits.
 177 */ 
 178static __inline__ int atomic_add_negative(int i, atomic_t *v)
 179{
 180        unsigned char c;
 181
 182        __asm__ __volatile__(
 183                LOCK "addl %2,%0; sets %1"
 184                :"=m" (v->counter), "=qm" (c)
 185                :"ir" (i), "m" (v->counter) : "memory");
 186        return c;
 187}
 188
 189/* These are x86-specific, used by some header files */
 190#define atomic_clear_mask(mask, addr) \
 191__asm__ __volatile__(LOCK "andl %0,%1" \
 192: : "r" (~(mask)),"m" (*addr) : "memory")
 193
 194#define atomic_set_mask(mask, addr) \
 195__asm__ __volatile__(LOCK "orl %0,%1" \
 196: : "r" (mask),"m" (*addr) : "memory")
 197
 198/* Atomic operations are already serializing on x86 */
 199#define smp_mb__before_atomic_dec()     barrier()
 200#define smp_mb__after_atomic_dec()      barrier()
 201#define smp_mb__before_atomic_inc()     barrier()
 202#define smp_mb__after_atomic_inc()      barrier()
 203
 204#endif
 205
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.