Go to the documentation of this file.00001
00022 #ifndef ATOMIC_H
00023 #define ATOMIC_H
00024
00025
00026
00027
00028
00029
00030 #define LOCK "lock ; "
00031
00032
00033
00034
00035
00036
00037 typedef struct { volatile int counter; } atomic_t;
00038
00039 #define ATOMIC_INIT(i) { (i) }
00040
00047 #define atomic_read(v) ((v)->counter)
00048
00056 #define atomic_set(v,i) (((v)->counter) = (i))
00057
00065 static __inline__ void atomic_add(int i, atomic_t *v)
00066 {
00067 __asm__ __volatile__(
00068 LOCK "addl %1,%0"
00069 :"=m" (v->counter)
00070 :"ir" (i), "m" (v->counter));
00071 }
00072
00080 static __inline__ void atomic_sub(int i, atomic_t *v)
00081 {
00082 __asm__ __volatile__(
00083 LOCK "subl %1,%0"
00084 :"=m" (v->counter)
00085 :"ir" (i), "m" (v->counter));
00086 }
00087
00088
00096 static __inline__ int atomic_add_return(int i, atomic_t *v)
00097 {
00098 int __i;
00099
00100 __i = i;
00101 __asm__ __volatile__(
00102 LOCK "xaddl %0, %1"
00103 :"+r" (i), "+m" (v->counter)
00104 : : "memory");
00105 return i + __i;
00106 }
00107
00108 static __inline__ int atomic_sub_return(int i, atomic_t *v)
00109 {
00110 return atomic_add_return(-i,v);
00111 }
00112
00113
00123 static __inline__ int atomic_sub_and_test(int i, atomic_t *v)
00124 {
00125 unsigned char c;
00126
00127 __asm__ __volatile__(
00128 LOCK "subl %2,%0; sete %1"
00129 :"=m" (v->counter), "=qm" (c)
00130 :"ir" (i), "m" (v->counter) : "memory");
00131 return c;
00132 }
00133
00140 static __inline__ void atomic_inc(atomic_t *v)
00141 {
00142 __asm__ __volatile__(
00143 LOCK "incl %0"
00144 :"=m" (v->counter)
00145 :"m" (v->counter));
00146 }
00147
00154 static __inline__ void atomic_dec(atomic_t *v)
00155 {
00156 __asm__ __volatile__(
00157 LOCK "decl %0"
00158 :"=m" (v->counter)
00159 :"m" (v->counter));
00160 }
00161
00170 static __inline__ int atomic_dec_and_test(atomic_t *v)
00171 {
00172 unsigned char c;
00173
00174 __asm__ __volatile__(
00175 LOCK "decl %0; sete %1"
00176 :"=m" (v->counter), "=qm" (c)
00177 :"m" (v->counter) : "memory");
00178 return c != 0;
00179 }
00180
00189 static __inline__ int atomic_inc_and_test(atomic_t *v)
00190 {
00191 unsigned char c;
00192
00193 __asm__ __volatile__(
00194 LOCK "incl %0; sete %1"
00195 :"=m" (v->counter), "=qm" (c)
00196 :"m" (v->counter) : "memory");
00197 return c != 0;
00198 }
00199
00209 static __inline__ int atomic_add_negative(int i, atomic_t *v)
00210 {
00211 unsigned char c;
00212
00213 __asm__ __volatile__(
00214 LOCK "addl %2,%0; sets %1"
00215 :"=m" (v->counter), "=qm" (c)
00216 :"ir" (i), "m" (v->counter) : "memory");
00217 return c;
00218 }
00219
00220
00221 #define atomic_clear_mask(mask, addr) \
00222 __asm__ __volatile__(LOCK "andl %0,%1" \
00223 : : "r" (~(mask)),"m" (*addr) : "memory")
00224
00225 #define atomic_set_mask(mask, addr) \
00226 __asm__ __volatile__(LOCK "orl %0,%1" \
00227 : : "r" (mask),"m" (*(addr)) : "memory")
00228
00229 #define atomic_inc_return(v) (atomic_add_return(1,v))
00230 #define atomic_dec_return(v) (atomic_sub_return(1,v))
00231
00232 #endif // ATOMIC_H