1#ifndef __ARCH_I386_ATOMIC__
2#define __ARCH_I386_ATOMIC__
3
4#include <linux/config.h>
5
6
7
8
9
10
11#ifdef CONFIG_SMP
12#define LOCK "lock ; "
13#else
14#define LOCK ""
15#endif
16
17
18
19
20
21
22typedef struct { volatile int counter; } atomic_t;
23
24#define ATOMIC_INIT(i) { (i) }
25
26
27
28
29
30
31
32
33#define atomic_read(v) ((v)->counter)
34
35
36
37
38
39
40
41
42
43#define atomic_set(v,i) (((v)->counter) = (i))
44
45
46
47
48
49
50
51
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
63
64
65
66
67
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
79
80
81
82
83
84
85
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
100
101
102
103
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
115
116
117
118
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
130
131
132
133
134
135
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
150
151
152
153
154
155
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
170
171
172
173
174
175
176
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
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
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