1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #ifndef _LOS_SPINLOCK_H
33 #define _LOS_SPINLOCK_H
34 #include "los_typedef.h"
35 #include "los_config.h"
36 #include "los_hwi.h"
37 #include "los_task.h"
38 #include "los_lockdep.h"
39
40 #ifdef __cplusplus
41 #if __cplusplus
42 extern "C" {
43 #endif /* __cplusplus */
44 #endif /* __cplusplus */
45
46 extern VOID ArchSpinLock(size_t *lock);
47 extern VOID ArchSpinUnlock(size_t *lock);
48 extern INT32 ArchSpinTrylock(size_t *lock);
49
50 typedef struct Spinlock {
51 size_t rawLock;
52 #ifdef LOSCFG_KERNEL_SMP
53 UINT32 cpuid;
54 VOID *owner;
55 const CHAR *name;
56 #endif
57 } SPIN_LOCK_S;
58
59 #ifdef LOSCFG_KERNEL_SMP_LOCKDEP
60 #define LOCKDEP_CHECK_IN(lock) OsLockDepCheckIn(lock)
61 #define LOCKDEP_RECORD(lock) OsLockDepRecord(lock)
62 #define LOCKDEP_CHECK_OUT(lock) OsLockDepCheckOut(lock)
63 #define LOCKDEP_CLEAR_LOCKS() OsLockdepClearSpinlocks()
64 #else
65 #define LOCKDEP_CHECK_IN(lock)
66 #define LOCKDEP_RECORD(lock)
67 #define LOCKDEP_CHECK_OUT(lock)
68 #define LOCKDEP_CLEAR_LOCKS()
69 #endif
70
71 #ifdef LOSCFG_KERNEL_SMP
72 #define SPINLOCK_OWNER_INIT NULL
73
74 #define SPIN_LOCK_INITIALIZER(lockName) \
75 { \
76 .rawLock = 0U, \
77 .cpuid = (UINT32)(-1), \
78 .owner = SPINLOCK_OWNER_INIT, \
79 .name = #lockName, \
80 }
81
82 /**
83 * @ingroup los_spinlock
84 * @brief Lock the spinlock.
85 *
86 * @par Description:
87 * This API is used to lock the spin lock.
88 *
89 * @attention None.
90 *
91 * @param lock [IN] Type #SPIN_LOCK_S spinlock pointer.
92 *
93 * @retval None.
94 * @par Dependency:
95 * <ul><li>los_spinlock.h: the header file that contains the API declaration.</li></ul>
96 * @see LOS_SpinUnlock
97 */
98 extern VOID LOS_SpinLock(SPIN_LOCK_S *lock);
99
100 /**
101 * @ingroup los_spinlock
102 * @brief Trying lock the spinlock.
103 *
104 * @par Description:
105 * This API is used to trying lock the spin lock.
106 *
107 * @attention None.
108 *
109 * @param lock [IN] Type #SPIN_LOCK_S spinlock pointer.
110 *
111 * @retval LOS_OK Got the spinlock.
112 * @retval LOS_NOK Not getting the spinlock.
113 * @par Dependency:
114 * <ul><li>los_spinlock.h: the header file that contains the API declaration.</li></ul>
115 * @see LOS_SpinLock
116 */
117 extern INT32 LOS_SpinTrylock(SPIN_LOCK_S *lock);
118
119 /**
120 * @ingroup los_spinlock
121 * @brief Unlock the spinlock.
122 *
123 * @par Description:
124 * This API is used to unlock the spin lock.
125 *
126 * @attention None.
127 *
128 * @param lock [IN] Type #SPIN_LOCK_S spinlock pointer.
129 *
130 * @retval None.
131 * @par Dependency:
132 * <ul><li>los_spinlock.h: the header file that contains the API declaration.</li></ul>
133 * @see LOS_SpinLock
134 */
135 extern VOID LOS_SpinUnlock(SPIN_LOCK_S *lock);
136
137 /**
138 * @ingroup los_spinlock
139 * @brief Lock the spinlock and disable all interrupts.
140 *
141 * @par Description:
142 * This API is used to lock the spin lock and disable all interrupts.
143 *
144 * @attention None.
145 *
146 * @param lock [IN] Type #SPIN_LOCK_S spinlock pointer.
147 * @param intSave [OUT] Type #UINT32 Saved interrupt flag for latter restored.
148 *
149 * @retval None.
150 * @par Dependency:
151 * <ul><li>los_spinlock.h: the header file that contains the API declaration.</li></ul>
152 * @see LOS_SpinLock
153 */
154 extern VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave);
155
156 /**
157 * @ingroup los_spinlock
158 * @brief Unlock the spinlock and restore interrupt flag.
159 *
160 * @par Description:
161 * This API is used to unlock the spin lock and restore interrupt flag.
162 *
163 * @attention None.
164 *
165 * @param lock [IN] Type #SPIN_LOCK_S spinlock pointer.
166 * @param intSave [IN] Type #UINT32 Interrupt flag to be restored.
167 *
168 * @retval None.
169 * @par Dependency:
170 * <ul><li>los_spinlock.h: the header file that contains the API declaration.</li></ul>
171 * @see LOS_SpinUnlock
172 */
173 extern VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave);
174
175 /**
176 * @ingroup los_spinlock
177 * @brief Check if holding the spinlock.
178 *
179 * @par Description:
180 * This API is used to check if holding the spinlock.
181 *
182 * @attention None.
183 *
184 * @param lock [IN] Type #SPIN_LOCK_S spinlock pointer.
185 *
186 * @retval TRUE Holding the spinlock.
187 * @retval FALSE Not Holding the spinlock.
188 * @par Dependency:
189 * <ul><li>los_spinlock.h: the header file that contains the API declaration.</li></ul>
190 */
191 extern BOOL LOS_SpinHeld(const SPIN_LOCK_S *lock);
192
193 /**
194 * @ingroup los_spinlock
195 * @brief Spinlock initialization.
196 *
197 * @par Description:
198 * This API is used to initialize a spinlock.
199 *
200 * @attention None.
201 *
202 * @param lock [IN] Type #SPIN_LOCK_S spinlock pointer.
203 *
204 * @retval None.
205 *
206 * @par Dependency:
207 * <ul><li>los_spinlock.h: the header file that contains the API declaration.</li></ul>
208 */
209 extern VOID LOS_SpinInit(SPIN_LOCK_S *lock);
210
211 #else
212 #define SPIN_LOCK_INITIALIZER(lockName) \
213 { \
214 .rawLock = 0U, \
215 }
216
217 /*
218 * For Non-SMP system, these apis does not handle with spinlocks,
219 * but for unifying the code of drivers, vendors and etc.
220 */
LOS_SpinLock(SPIN_LOCK_S * lock)221 LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinLock(SPIN_LOCK_S *lock)
222 {
223 (VOID)lock;
224 }
225
LOS_SpinTrylock(SPIN_LOCK_S * lock)226 LITE_OS_SEC_ALW_INLINE STATIC INLINE INT32 LOS_SpinTrylock(SPIN_LOCK_S *lock)
227 {
228 (VOID)lock;
229 return LOS_OK;
230 }
231
LOS_SpinUnlock(SPIN_LOCK_S * lock)232 LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinUnlock(SPIN_LOCK_S *lock)
233 {
234 (VOID)lock;
235 }
236
LOS_SpinLockSave(SPIN_LOCK_S * lock,UINT32 * intSave)237 LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave)
238 {
239 (VOID)lock;
240 *intSave = LOS_IntLock();
241 }
242
LOS_SpinUnlockRestore(SPIN_LOCK_S * lock,UINT32 intSave)243 LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave)
244 {
245 (VOID)lock;
246 LOS_IntRestore(intSave);
247 }
248
LOS_SpinHeld(const SPIN_LOCK_S * lock)249 LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_SpinHeld(const SPIN_LOCK_S *lock)
250 {
251 (VOID)lock;
252 return TRUE;
253 }
254
LOS_SpinInit(SPIN_LOCK_S * lock)255 LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_SpinInit(SPIN_LOCK_S *lock)
256 {
257 (VOID)lock;
258 }
259
260 #endif
261
262 #define SPIN_LOCK_INIT(lock) SPIN_LOCK_S lock = SPIN_LOCK_INITIALIZER(lock)
263
264 #ifdef __cplusplus
265 #if __cplusplus
266 }
267 #endif /* __cplusplus */
268 #endif /* __cplusplus */
269
270 #endif
271