Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* $Id: atomic.h,v 1.3 2001/07/25 16:15:19 bjornw Exp $ */ |
2 | ||
3 | #ifndef __ASM_CRIS_ATOMIC__ | |
4 | #define __ASM_CRIS_ATOMIC__ | |
5 | ||
9587997a AM |
6 | #include <linux/compiler.h> |
7 | ||
1da177e4 | 8 | #include <asm/system.h> |
8d20a541 | 9 | #include <asm/arch/atomic.h> |
1da177e4 LT |
10 | |
11 | /* | |
12 | * Atomic operations that C can't guarantee us. Useful for | |
13 | * resource counting etc.. | |
14 | */ | |
15 | ||
8d20a541 | 16 | typedef struct { volatile int counter; } atomic_t; |
1da177e4 LT |
17 | |
18 | #define ATOMIC_INIT(i) { (i) } | |
19 | ||
20 | #define atomic_read(v) ((v)->counter) | |
21 | #define atomic_set(v,i) (((v)->counter) = (i)) | |
22 | ||
23 | /* These should be written in asm but we do it in C for now. */ | |
24 | ||
d9b5444e | 25 | static inline void atomic_add(int i, volatile atomic_t *v) |
1da177e4 LT |
26 | { |
27 | unsigned long flags; | |
8d20a541 | 28 | cris_atomic_save(v, flags); |
1da177e4 | 29 | v->counter += i; |
8d20a541 | 30 | cris_atomic_restore(v, flags); |
1da177e4 LT |
31 | } |
32 | ||
d9b5444e | 33 | static inline void atomic_sub(int i, volatile atomic_t *v) |
1da177e4 LT |
34 | { |
35 | unsigned long flags; | |
8d20a541 | 36 | cris_atomic_save(v, flags); |
1da177e4 | 37 | v->counter -= i; |
8d20a541 | 38 | cris_atomic_restore(v, flags); |
1da177e4 LT |
39 | } |
40 | ||
d9b5444e | 41 | static inline int atomic_add_return(int i, volatile atomic_t *v) |
1da177e4 LT |
42 | { |
43 | unsigned long flags; | |
44 | int retval; | |
8d20a541 | 45 | cris_atomic_save(v, flags); |
1da177e4 | 46 | retval = (v->counter += i); |
8d20a541 | 47 | cris_atomic_restore(v, flags); |
1da177e4 LT |
48 | return retval; |
49 | } | |
50 | ||
51 | #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) | |
52 | ||
d9b5444e | 53 | static inline int atomic_sub_return(int i, volatile atomic_t *v) |
1da177e4 LT |
54 | { |
55 | unsigned long flags; | |
56 | int retval; | |
8d20a541 | 57 | cris_atomic_save(v, flags); |
1da177e4 | 58 | retval = (v->counter -= i); |
8d20a541 | 59 | cris_atomic_restore(v, flags); |
1da177e4 LT |
60 | return retval; |
61 | } | |
62 | ||
d9b5444e | 63 | static inline int atomic_sub_and_test(int i, volatile atomic_t *v) |
1da177e4 LT |
64 | { |
65 | int retval; | |
66 | unsigned long flags; | |
8d20a541 | 67 | cris_atomic_save(v, flags); |
1da177e4 | 68 | retval = (v->counter -= i) == 0; |
8d20a541 | 69 | cris_atomic_restore(v, flags); |
1da177e4 LT |
70 | return retval; |
71 | } | |
72 | ||
d9b5444e | 73 | static inline void atomic_inc(volatile atomic_t *v) |
1da177e4 LT |
74 | { |
75 | unsigned long flags; | |
8d20a541 | 76 | cris_atomic_save(v, flags); |
1da177e4 | 77 | (v->counter)++; |
8d20a541 | 78 | cris_atomic_restore(v, flags); |
1da177e4 LT |
79 | } |
80 | ||
d9b5444e | 81 | static inline void atomic_dec(volatile atomic_t *v) |
1da177e4 LT |
82 | { |
83 | unsigned long flags; | |
8d20a541 | 84 | cris_atomic_save(v, flags); |
1da177e4 | 85 | (v->counter)--; |
8d20a541 | 86 | cris_atomic_restore(v, flags); |
1da177e4 LT |
87 | } |
88 | ||
d9b5444e | 89 | static inline int atomic_inc_return(volatile atomic_t *v) |
1da177e4 LT |
90 | { |
91 | unsigned long flags; | |
92 | int retval; | |
8d20a541 | 93 | cris_atomic_save(v, flags); |
3c1d9303 | 94 | retval = ++(v->counter); |
8d20a541 | 95 | cris_atomic_restore(v, flags); |
1da177e4 LT |
96 | return retval; |
97 | } | |
98 | ||
d9b5444e | 99 | static inline int atomic_dec_return(volatile atomic_t *v) |
1da177e4 LT |
100 | { |
101 | unsigned long flags; | |
102 | int retval; | |
8d20a541 | 103 | cris_atomic_save(v, flags); |
3c1d9303 | 104 | retval = --(v->counter); |
8d20a541 | 105 | cris_atomic_restore(v, flags); |
1da177e4 LT |
106 | return retval; |
107 | } | |
d9b5444e | 108 | static inline int atomic_dec_and_test(volatile atomic_t *v) |
1da177e4 LT |
109 | { |
110 | int retval; | |
111 | unsigned long flags; | |
8d20a541 | 112 | cris_atomic_save(v, flags); |
1da177e4 | 113 | retval = --(v->counter) == 0; |
8d20a541 | 114 | cris_atomic_restore(v, flags); |
1da177e4 LT |
115 | return retval; |
116 | } | |
117 | ||
d9b5444e | 118 | static inline int atomic_inc_and_test(volatile atomic_t *v) |
1da177e4 LT |
119 | { |
120 | int retval; | |
121 | unsigned long flags; | |
8d20a541 | 122 | cris_atomic_save(v, flags); |
1da177e4 | 123 | retval = ++(v->counter) == 0; |
8d20a541 | 124 | cris_atomic_restore(v, flags); |
1da177e4 LT |
125 | return retval; |
126 | } | |
127 | ||
4a6dae6d NP |
128 | static inline int atomic_cmpxchg(atomic_t *v, int old, int new) |
129 | { | |
130 | int ret; | |
131 | unsigned long flags; | |
132 | ||
133 | cris_atomic_save(v, flags); | |
134 | ret = v->counter; | |
135 | if (likely(ret == old)) | |
136 | v->counter = new; | |
137 | cris_atomic_restore(v, flags); | |
138 | return ret; | |
139 | } | |
140 | ||
ffbf670f IM |
141 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) |
142 | ||
8426e1f6 NP |
143 | static inline int atomic_add_unless(atomic_t *v, int a, int u) |
144 | { | |
145 | int ret; | |
146 | unsigned long flags; | |
147 | ||
148 | cris_atomic_save(v, flags); | |
149 | ret = v->counter; | |
150 | if (ret != u) | |
151 | v->counter += a; | |
152 | cris_atomic_restore(v, flags); | |
153 | return ret != u; | |
154 | } | |
155 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) | |
156 | ||
1da177e4 LT |
157 | /* Atomic operations are already serializing */ |
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 | ||
d3cb4871 | 163 | #include <asm-generic/atomic.h> |
1da177e4 | 164 | #endif |