1 #ifndef _ASM_X86_ATOMIC_H 2 #define _ASM_X86_ATOMIC_H 3 4 #include <linux/compiler.h> 5 #include <linux/types.h> 6 #include <asm/processor.h> 7 8 typedef struct { volatile int counter; } atomic_t; 9 10 /* 11 * Atomic operations that C can't guarantee us. Useful for 12 * resource counting etc.. 13 */ 14 15 #define ATOMIC_INIT(i) { (i) } 16 17 /** 18 * atomic_read - read atomic variable 19 * @v: pointer of type atomic_t 20 * 21 * Atomically reads the value of @v. 22 */ 23 static inline int atomic_read(const atomic_t *v) 24 { 25 return ACCESS_ONCE((v)->counter); 26 } 27 28 /** 29 * atomic_set - set atomic variable 30 * @v: pointer of type atomic_t 31 * @i: required value 32 * 33 * Atomically sets the value of @v to @i. 34 */ 35 static inline void atomic_set(atomic_t *v, int i) 36 { 37 v->counter = i; 38 } 39 40 /** 41 * atomic_add - add integer to atomic variable 42 * @i: integer value to add 43 * @v: pointer of type atomic_t 44 * 45 * Atomically adds @i to @v. 46 */ 47 static inline void atomic_add(int i, atomic_t *v) 48 { 49 asm volatile(LOCK_PREFIX "addl %1,%0" 50 : "+m" (v->counter) 51 : "ir" (i)); 52 } 53 54 /** 55 * atomic_sub - subtract integer from atomic variable 56 * @i: integer value to subtract 57 * @v: pointer of type atomic_t 58 * 59 * Atomically subtracts @i from @v. 60 */ 61 static inline void atomic_sub(int i, atomic_t *v) 62 { 63 asm volatile(LOCK_PREFIX "subl %1,%0" 64 : "+m" (v->counter) 65 : "ir" (i)); 66 } 67 68 /** 69 * atomic_inc - increment atomic variable 70 * @v: pointer of type atomic_t 71 * 72 * Atomically increments @v by 1. 73 */ 74 static inline void atomic_inc(atomic_t *v) 75 { 76 asm volatile(LOCK_PREFIX "incl %0" 77 : "+m" (v->counter)); 78 } 79 80 /** 81 * atomic_dec - decrement atomic variable 82 * @v: pointer of type atomic_t 83 * 84 * Atomically decrements @v by 1. 85 */ 86 static inline void atomic_dec(atomic_t *v) 87 { 88 asm volatile(LOCK_PREFIX "decl %0" 89 : "+m" (v->counter)); 90 } 91 92 /** 93 * atomic_inc_short - increment of a short integer 94 * @v: pointer to type int 95 * 96 * Atomically adds 1 to @v 97 * Returns the new value of @u 98 */ 99 static inline short int atomic_inc_short(short int *v) 100 { 101 asm(LOCK_PREFIX "addw $1, %0" : "+m" (*v)); 102 return *v; 103 } 104 105 /* These are x86-specific, used by some header files */ 106 #define atomic_clear_mask(mask, addr) \ 107 asm volatile(LOCK_PREFIX "andl %0,%1" \ 108 : : "r" (~(mask)), "m" (*(addr)) : "memory") 109 110 #define atomic_set_mask(mask, addr) \ 111 asm volatile(LOCK_PREFIX "orl %0,%1" \ 112 : : "r" ((unsigned)(mask)), "m" (*(addr)) \ 113 : "memory") 114 115 #endif /* _ASM_X86_ATOMIC_H */ 116