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 * Atomic add one to the value at addr.
40 * Equal to rsAtomicAdd(addr, 1)
41 *
42 * @param addr Address of value to increment
43 *
44 * @return old value
45 */
46extern uint32_t __attribute__((overloadable))
47    rsAtomicInc(volatile uint32_t* addr);
48
49/**
50 * Atomic subtract one from the value at addr. Equal to rsAtomicSub(addr, 1)
51 *
52 * @param addr Address of value to decrement
53 *
54 * @return old value
55 */
56extern int32_t __attribute__((overloadable))
57    rsAtomicDec(volatile int32_t* addr);
58/**
59 * Atomic subtract one from the value at addr. Equal to rsAtomicSub(addr, 1)
60 *
61 * @param addr Address of value to decrement
62 *
63 * @return old value
64 */
65extern uint32_t __attribute__((overloadable))
66    rsAtomicDec(volatile uint32_t* addr);
67
68/**
69 * Atomic add a value to the value at addr.  addr[0] += value
70 *
71 * @param addr Address of value to modify
72 * @param value Amount to add to the value at addr
73 *
74 * @return old value
75 */
76extern int32_t __attribute__((overloadable))
77    rsAtomicAdd(volatile int32_t* addr, int32_t value);
78/**
79 * Atomic add a value to the value at addr.  addr[0] += value
80 *
81 * @param addr Address of value to modify
82 * @param value Amount to add to the value at addr
83 *
84 * @return old value
85 */
86extern uint32_t __attribute__((overloadable))
87    rsAtomicAdd(volatile uint32_t* addr, uint32_t value);
88
89/**
90 * Atomic Subtract a value from the value at addr.  addr[0] -= value
91 *
92 * @param addr Address of value to modify
93 * @param value Amount to subtract from the value at addr
94 *
95 * @return old value
96 */
97extern int32_t __attribute__((overloadable))
98    rsAtomicSub(volatile int32_t* addr, int32_t value);
99/**
100 * Atomic Subtract a value from the value at addr.  addr[0] -= value
101 *
102 * @param addr Address of value to modify
103 * @param value Amount to subtract from the value at addr
104 *
105 * @return old value
106 */
107extern uint32_t __attribute__((overloadable))
108    rsAtomicSub(volatile uint32_t* addr, uint32_t value);
109
110/**
111 * Atomic Bitwise and a value from the value at addr.  addr[0] &= value
112 *
113 * @param addr Address of value to modify
114 * @param value Amount to and with the value at addr
115 *
116 * @return old value
117 */
118extern int32_t __attribute__((overloadable))
119    rsAtomicAnd(volatile int32_t* addr, int32_t value);
120/**
121 * Atomic Bitwise and a value from the value at addr.  addr[0] &= value
122 *
123 * @param addr Address of value to modify
124 * @param value Amount to and with the value at addr
125 *
126 * @return old value
127 */
128extern uint32_t __attribute__((overloadable))
129    rsAtomicAnd(volatile uint32_t* addr, uint32_t value);
130
131/**
132 * Atomic Bitwise or a value from the value at addr.  addr[0] |= value
133 *
134 * @param addr Address of value to modify
135 * @param value Amount to or with the value at addr
136 *
137 * @return old value
138 */
139extern int32_t __attribute__((overloadable))
140    rsAtomicOr(volatile int32_t* addr, int32_t value);
141/**
142 * Atomic Bitwise or a value from the value at addr.  addr[0] |= value
143 *
144 * @param addr Address of value to modify
145 * @param value Amount to or with the value at addr
146 *
147 * @return old value
148 */
149extern uint32_t __attribute__((overloadable))
150    rsAtomicOr(volatile uint32_t* addr, uint32_t value);
151
152/**
153 * Atomic Bitwise xor a value from the value at addr.  addr[0] ^= value
154 *
155 * @param addr Address of value to modify
156 * @param value Amount to xor with the value at addr
157 *
158 * @return old value
159 */
160extern uint32_t __attribute__((overloadable))
161    rsAtomicXor(volatile uint32_t* addr, uint32_t value);
162/**
163 * Atomic Bitwise xor a value from the value at addr.  addr[0] ^= value
164 *
165 * @param addr Address of value to modify
166 * @param value Amount to xor with the value at addr
167 *
168 * @return old value
169 */
170extern int32_t __attribute__((overloadable))
171    rsAtomicXor(volatile int32_t* addr, int32_t value);
172
173/**
174 * Atomic Set the value at addr to the min of addr and value
175 * addr[0] = rsMin(addr[0], value)
176 *
177 * @param addr Address of value to modify
178 * @param value comparison value
179 *
180 * @return old value
181 */
182extern uint32_t __attribute__((overloadable))
183    rsAtomicMin(volatile uint32_t* addr, uint32_t value);
184/**
185 * Atomic Set the value at addr to the min of addr and value
186 * addr[0] = rsMin(addr[0], value)
187 *
188 * @param addr Address of value to modify
189 * @param value comparison value
190 *
191 * @return old value
192 */
193extern int32_t __attribute__((overloadable))
194    rsAtomicMin(volatile int32_t* addr, int32_t value);
195
196/**
197 * Atomic Set the value at addr to the max of addr and value
198 * addr[0] = rsMax(addr[0], value)
199 *
200 * @param addr Address of value to modify
201 * @param value comparison value
202 *
203 * @return old value
204 */
205extern uint32_t __attribute__((overloadable))
206    rsAtomicMax(volatile uint32_t* addr, uint32_t value);
207/**
208 * Atomic Set the value at addr to the max of addr and value
209 * addr[0] = rsMin(addr[0], value)
210 *
211 * @param addr Address of value to modify
212 * @param value comparison value
213 *
214 * @return old value
215 */
216extern int32_t __attribute__((overloadable))
217    rsAtomicMax(volatile int32_t* addr, int32_t value);
218
219/**
220 * Compare-and-set operation with a full memory barrier.
221 *
222 * If the value at addr matches compareValue then newValue is written.
223 *
224 * @param addr The address to compare and replace if the compare passes.
225 * @param compareValue The value to test addr[0] against.
226 * @param newValue The value to write if the test passes.
227 *
228 * @return old value
229 */
230extern int32_t __attribute__((overloadable))
231    rsAtomicCas(volatile int32_t* addr, int32_t compareValue, int32_t newValue);
232
233/**
234 * Compare-and-set operation with a full memory barrier.
235 *
236 * If the value at addr matches compareValue then newValue is written.
237 *
238 * @param addr The address to compare and replace if the compare passes.
239 * @param compareValue The value to test addr[0] against.
240 * @param newValue The value to write if the test passes.
241 *
242 * @return old value
243 */
244extern uint32_t __attribute__((overloadable))
245    rsAtomicCas(volatile uint32_t* addr, uint32_t compareValue, uint32_t newValue);
246
247#endif //defined(RS_VERSION) && (RS_VERSION >= 14)
248
249#endif
250
251