1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/** @file rs_atomic.rsh
18 *  \brief Atomic routines
19 *
20 *
21 */
22
23#ifndef __RS_ATOMIC_RSH__
24#define __RS_ATOMIC_RSH__
25
26#if (defined(RS_VERSION) && (RS_VERSION >= 14))
27
28/**
29 * Atomic add one to the value at addr.
30 * Equal to rsAtomicAdd(addr, 1)
31 *
32 * @param addr Address of value to increment
33 *
34 * @return old value
35 */
36extern int32_t __attribute__((overloadable))
37    rsAtomicInc(volatile int32_t* addr);
38
39/**
40 * Atomic subtract one from the value at addr. Equal to rsAtomicSub(addr, 1)
41 *
42 * @param addr Address of value to decrement
43 *
44 * @return old value
45 */
46extern int32_t __attribute__((overloadable))
47    rsAtomicDec(volatile int32_t* addr);
48
49/**
50 * Atomic add a value to the value at addr.  addr[0] += value
51 *
52 * @param addr Address of value to modify
53 * @param value Amount to add to the value at addr
54 *
55 * @return old value
56 */
57extern int32_t __attribute__((overloadable))
58    rsAtomicAdd(volatile int32_t* addr, int32_t value);
59
60/**
61 * Atomic Subtract a value from the value at addr.  addr[0] -= value
62 *
63 * @param addr Address of value to modify
64 * @param value Amount to subtract from the value at addr
65 *
66 * @return old value
67 */
68extern int32_t __attribute__((overloadable))
69    rsAtomicSub(volatile int32_t* addr, int32_t value);
70
71/**
72 * Atomic Bitwise and a value from the value at addr.  addr[0] &= value
73 *
74 * @param addr Address of value to modify
75 * @param value Amount to and with the value at addr
76 *
77 * @return old value
78 */
79extern int32_t __attribute__((overloadable))
80    rsAtomicAnd(volatile int32_t* addr, int32_t value);
81
82/**
83 * Atomic Bitwise or a value from the value at addr.  addr[0] |= value
84 *
85 * @param addr Address of value to modify
86 * @param value Amount to or with the value at addr
87 *
88 * @return old value
89 */
90extern int32_t __attribute__((overloadable))
91    rsAtomicOr(volatile int32_t* addr, int32_t value);
92
93/**
94 * Atomic Bitwise xor a value from the value at addr.  addr[0] ^= value
95 *
96 * @param addr Address of value to modify
97 * @param value Amount to xor with the value at addr
98 *
99 * @return old value
100 */
101extern int32_t __attribute__((overloadable))
102    rsAtomicXor(volatile int32_t* addr, int32_t value);
103
104/**
105 * Atomic Set the value at addr to the min of addr and value
106 * addr[0] = rsMin(addr[0], value)
107 *
108 * @param addr Address of value to modify
109 * @param value comparison value
110 *
111 * @return old value
112 */
113extern uint32_t __attribute__((overloadable))
114    rsAtomicMin(volatile uint32_t* addr, uint32_t value);
115/**
116 * Atomic Set the value at addr to the min of addr and value
117 * addr[0] = rsMin(addr[0], value)
118 *
119 * @param addr Address of value to modify
120 * @param value comparison value
121 *
122 * @return old value
123 */
124extern int32_t __attribute__((overloadable))
125    rsAtomicMin(volatile int32_t* addr, int32_t value);
126
127/**
128 * Atomic Set the value at addr to the max of addr and value
129 * addr[0] = rsMax(addr[0], value)
130 *
131 * @param addr Address of value to modify
132 * @param value comparison value
133 *
134 * @return old value
135 */
136extern uint32_t __attribute__((overloadable))
137    rsAtomicMax(volatile uint32_t* addr, uint32_t value);
138/**
139 * Atomic Set the value at addr to the max of addr and value
140 * addr[0] = rsMin(addr[0], value)
141 *
142 * @param addr Address of value to modify
143 * @param value comparison value
144 *
145 * @return old value
146 */
147extern int32_t __attribute__((overloadable))
148    rsAtomicMax(volatile int32_t* addr, int32_t value);
149
150/**
151 * Compare-and-set operation with a full memory barrier.
152 *
153 * If the value at addr matches compareValue then newValue is written.
154 *
155 * @param addr The address to compare and replace if the compare passes.
156 * @param compareValue The value to test addr[0] against.
157 * @param newValue The value to write if the test passes.
158 *
159 * @return old value
160 */
161extern int32_t __attribute__((overloadable))
162    rsAtomicCas(volatile int32_t* addr, int32_t compareValue, int32_t newValue);
163
164/**
165 * Compare-and-set operation with a full memory barrier.
166 *
167 * If the value at addr matches compareValue then newValue is written.
168 *
169 * @param addr The address to compare and replace if the compare passes.
170 * @param compareValue The value to test addr[0] against.
171 * @param newValue The value to write if the test passes.
172 *
173 * @return old value
174 */
175extern uint32_t __attribute__((overloadable))
176    rsAtomicCas(volatile uint32_t* addr, uint32_t compareValue, uint32_t newValue);
177
178#endif //defined(RS_VERSION) && (RS_VERSION >= 14)
179
180#if (defined(RS_VERSION) && (RS_VERSION >= 20))   // TODO: api 21
181
182/**
183 * Atomic add one to the value at addr.
184 * Equal to rsAtomicAdd(addr, 1)
185 *
186 * @param addr Address of value to increment
187 *
188 * @return old value
189 */
190extern int32_t __attribute__((overloadable))
191    rsAtomicInc(volatile uint32_t* addr);
192
193/**
194 * Atomic subtract one from the value at addr. Equal to rsAtomicSub(addr, 1)
195 *
196 * @param addr Address of value to decrement
197 *
198 * @return old value
199 */
200extern int32_t __attribute__((overloadable))
201    rsAtomicDec(volatile uint32_t* addr);
202
203/**
204 * Atomic add a value to the value at addr.  addr[0] += value
205 *
206 * @param addr Address of value to modify
207 * @param value Amount to add to the value at addr
208 *
209 * @return old value
210 */
211extern int32_t __attribute__((overloadable))
212    rsAtomicAdd(volatile uint32_t* addr, uint32_t value);
213
214/**
215 * Atomic Subtract a value from the value at addr.  addr[0] -= value
216 *
217 * @param addr Address of value to modify
218 * @param value Amount to subtract from the value at addr
219 *
220 * @return old value
221 */
222extern int32_t __attribute__((overloadable))
223    rsAtomicSub(volatile uint32_t* addr, uint32_t value);
224
225/**
226 * Atomic Bitwise and a value from the value at addr.  addr[0] &= value
227 *
228 * @param addr Address of value to modify
229 * @param value Amount to and with the value at addr
230 *
231 * @return old value
232 */
233extern int32_t __attribute__((overloadable))
234    rsAtomicAnd(volatile uint32_t* addr, uint32_t value);
235
236/**
237 * Atomic Bitwise or a value from the value at addr.  addr[0] |= value
238 *
239 * @param addr Address of value to modify
240 * @param value Amount to or with the value at addr
241 *
242 * @return old value
243 */
244extern int32_t __attribute__((overloadable))
245    rsAtomicOr(volatile uint32_t* addr, uint32_t value);
246
247/**
248 * Atomic Bitwise xor a value from the value at addr.  addr[0] ^= value
249 *
250 * @param addr Address of value to modify
251 * @param value Amount to xor with the value at addr
252 *
253 * @return old value
254 */
255extern int32_t __attribute__((overloadable))
256    rsAtomicXor(volatile uint32_t* addr, uint32_t value);
257
258#endif //defined(RS_VERSION) && (RS_VERSION >= 21)
259
260#endif
261
262