1
2
3
4
5
6
7
8
9
10
11#ifndef _ASM_ATOMIC_H
12#define _ASM_ATOMIC_H
13
14#ifdef CONFIG_SMP
15#error not SMP safe
16#endif
17
18
19
20
21
22
23
24
25
26
27
28typedef struct {
29 int counter;
30} atomic_t;
31
32#define ATOMIC_INIT(i) { (i) }
33
34#ifdef __KERNEL__
35
36
37
38
39
40
41
42
43#define atomic_read(v) ((v)->counter)
44
45
46
47
48
49
50
51
52
53#define atomic_set(v, i) (((v)->counter) = (i))
54
55#include <asm/system.h>
56
57
58
59
60
61
62
63
64
65static inline int atomic_add_return(int i, atomic_t *v)
66{
67 unsigned long flags;
68 int temp;
69
70 local_irq_save(flags);
71 temp = v->counter;
72 temp += i;
73 v->counter = temp;
74 local_irq_restore(flags);
75
76 return temp;
77}
78
79
80
81
82
83
84
85
86
87static inline int atomic_sub_return(int i, atomic_t *v)
88{
89 unsigned long flags;
90 int temp;
91
92 local_irq_save(flags);
93 temp = v->counter;
94 temp -= i;
95 v->counter = temp;
96 local_irq_restore(flags);
97
98 return temp;
99}
100
101static inline int atomic_add_negative(int i, atomic_t *v)
102{
103 return atomic_add_return(i, v) < 0;
104}
105
106static inline void atomic_add(int i, atomic_t *v)
107{
108 atomic_add_return(i, v);
109}
110
111static inline void atomic_sub(int i, atomic_t *v)
112{
113 atomic_sub_return(i, v);
114}
115
116static inline void atomic_inc(atomic_t *v)
117{
118 atomic_add_return(1, v);
119}
120
121static inline void atomic_dec(atomic_t *v)
122{
123 atomic_sub_return(1, v);
124}
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#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
130#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
131#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0)
132
133#define atomic_add_unless(v, a, u) \
134({ \
135 int c, old; \
136 c = atomic_read(v); \
137 while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
138 c = old; \
139 c != (u); \
140})
141
142#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
143
144static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
145{
146 unsigned long flags;
147
148 mask = ~mask;
149 local_irq_save(flags);
150 *addr &= mask;
151 local_irq_restore(flags);
152}
153
154#define atomic_xchg(ptr, v) (xchg(&(ptr)->counter, (v)))
155#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new)))
156
157
158#define smp_mb__before_atomic_dec() barrier()
159#define smp_mb__after_atomic_dec() barrier()
160#define smp_mb__before_atomic_inc() barrier()
161#define smp_mb__after_atomic_inc() barrier()
162
163#include <asm-generic/atomic.h>
164
165#endif
166#endif
167