• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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