• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------------
2  * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved.
3  * Description : los atomic.
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  * 1. Redistributions of source code must retain the above copyright notice, this list of
7  * conditions and the following disclaimer.
8  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
9  * of conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
12  * to endorse or promote products derived from this software without specific prior written
13  * permission.
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  * ---------------------------------------------------------------------------- */
26 
27 /**
28  * @defgroup los_atomic Atomic
29  * @ingroup kernel
30  */
31 
32 #ifndef _LOS_ATOMIC_H
33 #define _LOS_ATOMIC_H
34 
35 #include "los_hwi.h"
36 #include "los_typedef.h"
37 
38 #ifdef __cplusplus
39 #if __cplusplus
40 extern "C" {
41 #endif /* __cplusplus */
42 #endif /* __cplusplus */
43 
44 /**
45 * @ingroup  los_atomic
46 * @brief Atomic addition.
47 *
48 * @par Description:
49 * This API is used to implement the atomic addition and return the result value of the augend.
50 * @attention
51 * <ul>
52 * <li>The pointer val must not be NULL.</li>
53 * <li>If the addtion result is not in the range of representable values for 32-bit signed integer,
54 * an int integer overflow may occur to the return value</li>
55 * </ul>
56 *
57 * @param  val      [IN] The augend pointer.
58 * @param  addVal   [IN] The addend.
59 *
60 * @retval #INT32  The result value of the augend.
61 * @par Dependency:
62 * <ul><li>los_atomic.h: the header file that contains the API declaration.</li></ul>
63 * @see
64 */
LOS_AtomicAdd(volatile INT32 * val,INT32 addVal)65 static inline INT32 LOS_AtomicAdd(volatile INT32 *val, INT32 addVal)
66 {
67     INT32 tmp;
68     UINT32 intStatus;
69     intStatus = LOS_IntLock();
70     tmp = *val;
71     tmp += addVal;
72     *val = tmp;
73     LOS_IntRestore(intStatus);
74     return tmp;
75 }
76 
77 /**
78 * @ingroup  los_atomic
79 * @brief Atomic subtraction.
80 *
81 * @par Description:
82 * This API is used to implement the atomic subtraction and return the result value of the minuend.
83 * @attention
84 * <ul>
85 * <li>The pointer val must not be NULL.</li>
86 * <li>If the subtraction result is not in the range of representable values for 32-bit signed integer,
87 * an int integer overflow may occur to the return value</li>
88 * </ul>
89 *
90 * @param  val       [IN] The minuend pointer.
91 * @param  addVal    [IN] The subtrahend.
92 *
93 * @retval #INT32  The result value of the minuend.
94 * @par Dependency:
95 * <ul><li>los_atomic.h: the header file that contains the API declaration.</li></ul>
96 * @see
97 */
LOS_AtomicSub(volatile INT32 * val,INT32 addVal)98 static inline INT32 LOS_AtomicSub(volatile INT32 *val, INT32 addVal)
99 {
100     INT32 tmp;
101     UINT32 intStatus;
102     intStatus = LOS_IntLock();
103     tmp = *val;
104     tmp -= addVal;
105     *val = tmp;
106     LOS_IntRestore(intStatus);
107     return tmp;
108 }
109 /**
110 * @ingroup  los_atomic
111 * @brief Atomic addSelf.
112 *
113 * @par Description:
114 * This API is used to implement the atomic addSelf .
115 * @attention
116 * <ul>
117 * <li>The pointer addr must not be NULL.</li>
118 * <li>The value which addr point to must not be INT_MAX to avoid integer overflow after adding 1.</li>
119 * </ul>
120 *
121 * @param  addr      [IN] The addSelf variable pointer.
122 *
123 * @retval none.
124 * @par Dependency:
125 * <ul><li>los_atomic.h: the header file that contains the API declaration.</li></ul>
126 * @see
127 */
LOS_AtomicInc(volatile INT32 * addr)128 static inline VOID LOS_AtomicInc(volatile INT32 *addr)
129 {
130     UINT32 intStatus;
131     intStatus = LOS_IntLock();
132     (*addr)++;
133     LOS_IntRestore(intStatus);
134 }
135 
136 /**
137 * @ingroup  los_atomic
138 * @brief Atomic addSelf.
139 *
140 * @par Description:
141 * This API is used to implement the atomic addSelf and return the result of addSelf.
142 * @attention
143 * <ul>
144 * <li>The pointer addr must not be NULL.</li>
145 * <li>The value which pswAddr point to must not be INT_MAX to avoid integer overflow after adding 1.</li>
146 * </ul>
147 *
148 * @param  addr      [IN] The addSelf variable pointer.
149 *
150 * @retval #INT32 The return value of variable addSelf.
151 * @par Dependency:
152 * <ul><li>los_atomic.h: the header file that contains the API declaration.</li></ul>
153 * @see
154 */
LOS_AtomicIncRet(volatile INT32 * addr)155 static inline INT32 LOS_AtomicIncRet(volatile INT32 *addr)
156 {
157     INT32 tmp;
158     UINT32 intStatus;
159     intStatus = LOS_IntLock();
160     tmp = *addr;
161     tmp++;
162     *addr = tmp;
163     LOS_IntRestore(intStatus);
164     return tmp;
165 }
166 
167 /**
168 * @ingroup  los_atomic
169 * @brief Atomic auto-decrement.
170 *
171 * @par Description:
172 * This API is used to implementating the atomic auto-decrement.
173 * @attention
174 * <ul>
175 * <li>The pointer addr must not be NULL.</li>
176 * <li>The value which pswAddr point to must not be INT_MIN to avoid overflow after reducing 1.</li>
177 * </ul>
178 *
179 * @param  addr      [IN] The auto-decrement variable pointer.
180 *
181 * @retval none.
182 * @par Dependency:
183 * <ul><li>los_atomic.h: the header file that contains the API declaration.</li></ul>
184 * @see
185 */
LOS_AtomicDec(volatile INT32 * addr)186 static inline VOID LOS_AtomicDec(volatile INT32 *addr)
187 {
188     UINT32 intStatus;
189     intStatus = LOS_IntLock();
190     (*addr)--;
191     LOS_IntRestore(intStatus);
192 }
193 
194 /**
195 * @ingroup  los_atomic
196 * @brief Atomic auto-decrement.
197 *
198 * @par Description:
199 * This API is used to implementating the atomic auto-decrement and return the result of auto-decrement.
200 * @attention
201 * <ul>
202 * <li>The pointer addr must not be NULL.</li>
203 * <li>The value which pswAddr point to must not be INT_MIN to avoid overflow after reducing 1.</li>
204 * </ul>
205 *
206 * @param  addr      [IN] The addSelf variable pointer.
207 *
208 * @retval #INT32  The return value of variable auto-decrement.
209 * @par Dependency:
210 * <ul><li>los_atomic.h: the header file that contains the API declaration.</li></ul>
211 * @see
212 */
LOS_AtomicDecRet(volatile INT32 * addr)213 static inline INT32 LOS_AtomicDecRet(volatile INT32 *addr)
214 {
215     INT32 tmp;
216     UINT32 intStatus;
217     intStatus = LOS_IntLock();
218     tmp = *addr;
219     tmp--;
220     *addr = tmp;
221     LOS_IntRestore(intStatus);
222     return tmp;
223 }
224 
225 /**
226 * @ingroup  los_atomic
227 * @brief Atomic exchange for 32-bit variable.
228 *
229 * @par Description:
230 * This API is used to implement the atomic exchange for 32-bit variable and return the previous value of
231 * the atomic variable.
232 * @attention
233 * <ul>The pointer addr must not be NULL.</ul>
234 *
235 * @param  addr       [IN] The variable pointer.
236 * @param  value      [IN] The exchange value.
237 *
238 * @retval #INT32       The previous value of the atomic variable
239 * @par Dependency:
240 * <ul><li>los_atomic.h: the header file that contains the API declaration.</li></ul>
241 * @see
242 */
LOS_AtomicXchg32bits(volatile INT32 * addr,INT32 value)243 static inline INT32 LOS_AtomicXchg32bits(volatile INT32 *addr, INT32 value)
244 {
245     INT32 prevVal;
246     UINT32 intStatus;
247     intStatus = LOS_IntLock();
248     prevVal = *addr;
249     *addr = value;
250     LOS_IntRestore(intStatus);
251     return prevVal;
252 }
253 
254 /**
255 * @ingroup  los_atomic
256 * @brief Atomic exchange for 32-bit variable with compare.
257 *
258 * @par Description:
259 * This API is used to implement the atomic exchange for 32-bit variable, if the value of variable is equal to swOldVal.
260 * @attention
261 * <ul>The pointer addr must not be NULL.</ul>
262 *
263 * @param  addr        [IN] The variable pointer.
264 * @param  newVal      [IN] The new value.
265 * @param  oldVal      [IN] The old value.
266 *
267 * @retval TRUE  The previous value of the atomic variable is not equal to swOldVal.
268 * @retval FALSE The previous value of the atomic variable is equal to swOldVal.
269 * @par Dependency:
270 * <ul><li>los_atomic.h: the header file that contains the API declaration.</li></ul>
271 * @see
272 */
LOS_AtomicCmpXchg32bits(volatile INT32 * addr,INT32 newVal,INT32 oldVal)273 static inline BOOL LOS_AtomicCmpXchg32bits(volatile INT32 *addr, INT32 newVal, INT32 oldVal)
274 {
275     INT32 prevVal;
276     UINT32 intStatus = LOS_IntLock();
277     prevVal = *addr;
278     if (*addr == oldVal) {
279         *addr = newVal;
280     }
281     LOS_IntRestore(intStatus);
282     return (prevVal != oldVal);
283 }
284 
285 #ifdef __cplusplus
286 #if __cplusplus
287 }
288 #endif /* __cplusplus */
289 #endif /* __cplusplus */
290 
291 #endif /* _LOS_ATOMIC_H */
292