]>
Commit | Line | Data |
---|---|---|
867e359b CM |
1 | /* |
2 | * Copyright 2010 Tilera Corporation. All Rights Reserved. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU General Public License | |
6 | * as published by the Free Software Foundation, version 2. | |
7 | * | |
8 | * This program is distributed in the hope that it will be useful, but | |
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | |
11 | * NON INFRINGEMENT. See the GNU General Public License for | |
12 | * more details. | |
13 | * | |
14 | * Atomic primitives. | |
15 | */ | |
16 | ||
17 | #ifndef _ASM_TILE_ATOMIC_H | |
18 | #define _ASM_TILE_ATOMIC_H | |
19 | ||
34f2c0ac PG |
20 | #include <asm/cmpxchg.h> |
21 | ||
867e359b CM |
22 | #ifndef __ASSEMBLY__ |
23 | ||
24 | #include <linux/compiler.h> | |
bd119c69 | 25 | #include <linux/types.h> |
867e359b CM |
26 | |
27 | #define ATOMIC_INIT(i) { (i) } | |
28 | ||
29 | /** | |
30 | * atomic_read - read atomic variable | |
31 | * @v: pointer of type atomic_t | |
32 | * | |
33 | * Atomically reads the value of @v. | |
34 | */ | |
35 | static inline int atomic_read(const atomic_t *v) | |
36 | { | |
d356b595 | 37 | return ACCESS_ONCE(v->counter); |
867e359b CM |
38 | } |
39 | ||
40 | /** | |
41 | * atomic_sub_return - subtract integer and return | |
42 | * @v: pointer of type atomic_t | |
43 | * @i: integer value to subtract | |
44 | * | |
45 | * Atomically subtracts @i from @v and returns @v - @i | |
46 | */ | |
47 | #define atomic_sub_return(i, v) atomic_add_return((int)(-(i)), (v)) | |
48 | ||
49 | /** | |
50 | * atomic_sub - subtract integer from atomic variable | |
51 | * @i: integer value to subtract | |
52 | * @v: pointer of type atomic_t | |
53 | * | |
54 | * Atomically subtracts @i from @v. | |
55 | */ | |
56 | #define atomic_sub(i, v) atomic_add((int)(-(i)), (v)) | |
57 | ||
58 | /** | |
59 | * atomic_sub_and_test - subtract value from variable and test result | |
60 | * @i: integer value to subtract | |
61 | * @v: pointer of type atomic_t | |
62 | * | |
63 | * Atomically subtracts @i from @v and returns true if the result is | |
64 | * zero, or false for all other cases. | |
65 | */ | |
66 | #define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0) | |
67 | ||
68 | /** | |
69 | * atomic_inc_return - increment memory and return | |
70 | * @v: pointer of type atomic_t | |
71 | * | |
72 | * Atomically increments @v by 1 and returns the new value. | |
73 | */ | |
74 | #define atomic_inc_return(v) atomic_add_return(1, (v)) | |
75 | ||
76 | /** | |
77 | * atomic_dec_return - decrement memory and return | |
78 | * @v: pointer of type atomic_t | |
79 | * | |
80 | * Atomically decrements @v by 1 and returns the new value. | |
81 | */ | |
82 | #define atomic_dec_return(v) atomic_sub_return(1, (v)) | |
83 | ||
84 | /** | |
85 | * atomic_inc - increment atomic variable | |
86 | * @v: pointer of type atomic_t | |
87 | * | |
88 | * Atomically increments @v by 1. | |
89 | */ | |
90 | #define atomic_inc(v) atomic_add(1, (v)) | |
91 | ||
92 | /** | |
93 | * atomic_dec - decrement atomic variable | |
94 | * @v: pointer of type atomic_t | |
95 | * | |
96 | * Atomically decrements @v by 1. | |
97 | */ | |
98 | #define atomic_dec(v) atomic_sub(1, (v)) | |
99 | ||
100 | /** | |
101 | * atomic_dec_and_test - decrement and test | |
102 | * @v: pointer of type atomic_t | |
103 | * | |
104 | * Atomically decrements @v by 1 and returns true if the result is 0. | |
105 | */ | |
106 | #define atomic_dec_and_test(v) (atomic_dec_return(v) == 0) | |
107 | ||
108 | /** | |
109 | * atomic_inc_and_test - increment and test | |
110 | * @v: pointer of type atomic_t | |
111 | * | |
112 | * Atomically increments @v by 1 and returns true if the result is 0. | |
113 | */ | |
114 | #define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) | |
115 | ||
6dc9658f CM |
116 | /** |
117 | * atomic_xchg - atomically exchange contents of memory with a new value | |
118 | * @v: pointer of type atomic_t | |
119 | * @i: integer value to store in memory | |
120 | * | |
121 | * Atomically sets @v to @i and returns old @v | |
122 | */ | |
123 | static inline int atomic_xchg(atomic_t *v, int n) | |
124 | { | |
125 | return xchg(&v->counter, n); | |
126 | } | |
127 | ||
128 | /** | |
129 | * atomic_cmpxchg - atomically exchange contents of memory if it matches | |
130 | * @v: pointer of type atomic_t | |
131 | * @o: old value that memory should have | |
132 | * @n: new value to write to memory if it matches | |
133 | * | |
134 | * Atomically checks if @v holds @o and replaces it with @n if so. | |
135 | * Returns the old value at @v. | |
136 | */ | |
137 | static inline int atomic_cmpxchg(atomic_t *v, int o, int n) | |
138 | { | |
139 | return cmpxchg(&v->counter, o, n); | |
140 | } | |
141 | ||
867e359b CM |
142 | /** |
143 | * atomic_add_negative - add and test if negative | |
144 | * @v: pointer of type atomic_t | |
145 | * @i: integer value to add | |
146 | * | |
147 | * Atomically adds @i to @v and returns true if the result is | |
148 | * negative, or false when result is greater than or equal to zero. | |
149 | */ | |
150 | #define atomic_add_negative(i, v) (atomic_add_return((i), (v)) < 0) | |
151 | ||
867e359b CM |
152 | #endif /* __ASSEMBLY__ */ |
153 | ||
154 | #ifndef __tilegx__ | |
155 | #include <asm/atomic_32.h> | |
156 | #else | |
157 | #include <asm/atomic_64.h> | |
158 | #endif | |
159 | ||
adf6d9b3 CM |
160 | #ifndef __ASSEMBLY__ |
161 | ||
6dc9658f CM |
162 | /** |
163 | * atomic64_xchg - atomically exchange contents of memory with a new value | |
164 | * @v: pointer of type atomic64_t | |
165 | * @i: integer value to store in memory | |
166 | * | |
167 | * Atomically sets @v to @i and returns old @v | |
168 | */ | |
b924a690 | 169 | static inline long long atomic64_xchg(atomic64_t *v, long long n) |
6dc9658f CM |
170 | { |
171 | return xchg64(&v->counter, n); | |
172 | } | |
173 | ||
174 | /** | |
175 | * atomic64_cmpxchg - atomically exchange contents of memory if it matches | |
176 | * @v: pointer of type atomic64_t | |
177 | * @o: old value that memory should have | |
178 | * @n: new value to write to memory if it matches | |
179 | * | |
180 | * Atomically checks if @v holds @o and replaces it with @n if so. | |
181 | * Returns the old value at @v. | |
182 | */ | |
b924a690 CG |
183 | static inline long long atomic64_cmpxchg(atomic64_t *v, long long o, |
184 | long long n) | |
6dc9658f CM |
185 | { |
186 | return cmpxchg64(&v->counter, o, n); | |
187 | } | |
188 | ||
adf6d9b3 CM |
189 | static inline long long atomic64_dec_if_positive(atomic64_t *v) |
190 | { | |
191 | long long c, old, dec; | |
192 | ||
193 | c = atomic64_read(v); | |
194 | for (;;) { | |
195 | dec = c - 1; | |
196 | if (unlikely(dec < 0)) | |
197 | break; | |
198 | old = atomic64_cmpxchg((v), c, dec); | |
199 | if (likely(old == c)) | |
200 | break; | |
201 | c = old; | |
202 | } | |
203 | return dec; | |
204 | } | |
205 | ||
206 | #endif /* __ASSEMBLY__ */ | |
207 | ||
867e359b | 208 | #endif /* _ASM_TILE_ATOMIC_H */ |