1 /*
2 * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
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; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #ifndef __HI_ATOMIC_H__
20 #define __HI_ATOMIC_H__
21 #include <hi_types.h>
22 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
23 #include <los_hwi.h>
24 #endif
25
26 #ifdef __cplusplus
27 #if __cplusplus
28 extern "C" {
29 #endif
30 #endif
31
32 typedef struct {
33 volatile hi_s32 counter;
34 } hi_atomic;
35
36 #define hi_atomic_init(i) { (i) }
37 #define hi_atomic_read(v) ((v)->counter)
38 #define hi_atomic_set(v, i) (((v)->counter) = (i))
39
40 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
41 #define hi_atomic_inc(v) hi_atomic_add_return(1, v)
42 #define hi_atomic_dec(v) hi_atomic_sub_return(1, v)
43
44 #define hi_atomic_inc_return(v) (hi_atomic_add_return(1, v))
45 #define hi_atomic_dec_return(v) (hi_atomic_sub_return(1, v))
46 #define hi_atomic_inc_return_optimize(v) (hi_atomic_add_return_optimize(1, v))
47 #elif (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION)
48 #define hi_atomic_inc(v) atomic_add_return(1, (atomic_t *)v)
49 #define hi_atomic_dec(v) atomic_sub_return(1, (atomic_t *)v)
50 #define hi_atomic_inc_return(v) (atomic_add_return(1, (atomic_t *)v))
51 #define hi_atomic_dec_return(v) (atomic_sub_return(1, (atomic_t *)v))
52 #endif /* _PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION */
53
54 /* *
55 * @ingroup iot_atomic
56 * If the atomic operation is performed, the operation result is returned.
57 CNcomment:原子加操作,返回操作结果CNend
58 */
59 #define hi_atomic_add_return_op(i, v) (hi_atomic_add_return(i, v))
60
61 /* *
62 * @ingroup iot_atomic
63 * The operation result is returned when the atomic subtraction operation is performed.
64 CNcomment:原子减操作,返回操作结果CNend
65 */
66 #define hi_atomic_sub_return_op(i, v) (hi_atomic_sub_return(i, v))
67
68 /* *
69 * @ingroup iot_atomic
70 * The specified bit in the atomic setting variable is 1.
71 CNcomment:原子设置变量中指定bit位为1CNend
72 */
73 #define hi_atomic_bit_set_op(bit, v) (hi_atomic_bit_set(bit, v))
74 /* *
75 * @ingroup iot_atomic
76 * The specified bit in the atomic setting variable is 0.
77 CNcomment:原子设置变量中指定bit位为0CNend
78 */
79 #define hi_atomic_bit_clear_op(bit, v) (hi_atomic_bit_clear(bit, v))
80
81 #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
82 /* *
83 * @ingroup iot_atomic
84 * @brief If the atomic operation is performed, the operation result is returned.
85 CNcomment:原子加操作,返回操作结果CNend
86 *
87 * @par 描述:
88 * If the atomic operation is performed, the operation result is returned.
89 CNcomment:原子加操作,返回操作结果CNend
90 *
91 * @attention None
92 * @param i [IN] type #hi_s32, The number of operands added to an atom.CNcomment:与原子相加的操作数CNend
93 * @param v [IN] type #hi_atomic*,Pointer to the atomic structure address.CNcomment:原子结构地址指针CNend
94 *
95 * @retval #hi_s32 Add Operation Result. CNcomment:加操作结果CNend
96 * @par 依赖:
97 * @li hi_atomic.h:Header file where the interface declaration is located.
98 CNcomment:该接口声明所在的头文件。CNend
99 * @see None
100 * @since Hi3861_V100R001C00
101 */
hi_atomic_add_return(hi_s32 i,hi_atomic * v)102 static inline hi_s32 hi_atomic_add_return(hi_s32 i, hi_atomic *v)
103 {
104 hi_u32 irq_status;
105
106 irq_status = LOS_IntLock();
107 v->counter += i;
108 (hi_void)LOS_IntRestore(irq_status);
109 return v->counter;
110 }
111
112 /* *
113 * @ingroup iot_atomic
114 * @brief The operation result is returned when the atomic subtraction operation is performed.
115 CNcomment:原子减操作,返回操作结果CNend
116 *
117 * @par 描述:
118 * The operation result is returned when the atomic subtraction operation is performed.
119 CNcomment:原子减操作,返回操作结果CNend
120 *
121 * @attention None
122 * @param i [IN] type #hi_s32, The number of operands subtracted from the atom.
123 CNcomment:被原子相减的操作数CNend
124 * @param v [IN] type #hi_atomic*,Pointer to the atomic structure address.CNcomment:原子结构地址指针CNend
125 *
126 * @retval #hi_s32 Reduce the operation result. CNcomment:减操作结果CNend
127 * @par 依赖:
128 * @li hi_atomic.h:Header file where the interface declaration is located.
129 CNcomment:该接口声明所在的头文件。CNend
130 * @see None
131 * @since Hi3861_V100R001C00
132 */
hi_atomic_sub_return(hi_s32 i,hi_atomic * v)133 static inline hi_s32 hi_atomic_sub_return(hi_s32 i, hi_atomic *v)
134 {
135 hi_u32 irq_status;
136
137 irq_status = LOS_IntLock();
138 v->counter = v->counter - i;
139 (hi_void)LOS_IntRestore(irq_status);
140
141 return v->counter;
142 }
143
144 /* *
145 * @ingroup iot_atomic
146 * @brief The specified bit in the atomic setting variable is 1.CNcomment:原子设置变量中指定bit位为1CNend
147 *
148 * @par 描述:
149 * The specified bit in the atomic setting variable is 1.CNcomment:原子设置变量中指定bit位为1CNend
150 *
151 * @attention None
152 * @param bit [IN] type #hi_s32, Position of the bit that is set to 1. The value range is 0-31.
153 CNcomment:被置1的bit位置,范围0-31.CNend
154 * @param value [IN] type #hi_u32*,Address pointer of the set variable.CNcomment:置位变量的地址指针CNend
155 *
156 * @retval #None
157 * @par 依赖:
158 * @li hi_atomic.h:Header file where the interface declaration is located.
159 CNcomment:该接口声明所在的头文件。CNend
160 * @see None
161 * @since Hi3861_V100R001C00
162 */
hi_atomic_bit_set(hi_s32 bit,volatile hi_u32 * value)163 static inline hi_void hi_atomic_bit_set(hi_s32 bit, volatile hi_u32 *value)
164 {
165 hi_u32 irq_status;
166 irq_status = LOS_IntLock();
167
168 *value |= (1 << bit);
169
170 (hi_void)LOS_IntRestore(irq_status);
171 }
172
173 /* *
174 * @ingroup iot_atomic
175 * @brief The specified bit in the atomic setting variable is 0.CNcomment:原子设置变量中指定bit位为0CNend
176 *
177 * @par 描述:
178 * The specified bit in the atomic setting variable is 0.CNcomment:原子设置变量中指定bit位为0CNend
179 *
180 * @attention None
181 * @param bit [IN] type #hi_s32, Position of the bit that is set to 0. The value range is 0-31.
182 CNcomment:被置0的bit位置,范围0-31.CNend
183 * @param value [IN] type #hi_u32*,Address pointer of the set variable.CNcomment:置位变量的地址指针CNend
184 *
185 * @retval #None
186 * @par 依赖:
187 * @li hi_atomic.h:Header file where the interface declaration is located.
188 CNcomment:该接口声明所在的头文件。CNend
189 * @see None
190 * @since Hi3861_V100R001C00
191 */
hi_atomic_bit_clear(hi_s32 bit,volatile hi_u32 * value)192 static inline hi_void hi_atomic_bit_clear(hi_s32 bit, volatile hi_u32 *value)
193 {
194 hi_u32 irq_status;
195 hi_u32 mask;
196
197 irq_status = LOS_IntLock();
198 mask = 1 << bit;
199 *value = (*value) & (~mask);
200
201 (hi_void)LOS_IntRestore(irq_status);
202 }
203
hi_atomic_add_return_optimize(hi_s32 i,hi_atomic * v)204 __attribute__((always_inline)) static inline hi_s32 hi_atomic_add_return_optimize(hi_s32 i, hi_atomic *v)
205 {
206 hi_u32 irq_status;
207
208 irq_status = LOS_IntLock();
209 v->counter += i;
210 (hi_void)LOS_IntRestore(irq_status);
211 return v->counter;
212 }
213 #endif /* #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) */
214
215 #ifdef __cplusplus
216 #if __cplusplus
217 }
218 #endif
219 #endif
220
221 #endif /* end of hi_atomic.h */
222