1 /* 2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 3 * Copyright (c) 2020-2022 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 /** 33 * @defgroup los_rwlock Rwlock 34 * @ingroup kernel 35 */ 36 37 #ifndef _LOS_RWLOCK_H 38 #define _LOS_RWLOCK_H 39 40 #include "los_base.h" 41 42 #ifdef __cplusplus 43 #if __cplusplus 44 extern "C" { 45 #endif /* __cplusplus */ 46 #endif /* __cplusplus */ 47 48 /** 49 * @ingroup los_rwlock 50 * Rwlock object. 51 */ 52 typedef struct OsRwlock { 53 INT32 magic : 24; /**< Magic number */ 54 INT32 rwCount : 8; /**< Times of locking the rwlock, rwCount > 0 when rwkick is read mode, rwCount < 0 55 when the rwlock is write mode, rwCount = 0 when the lock is free. */ 56 VOID *writeOwner; /**< The current write thread that is locking the rwlock */ 57 LOS_DL_LIST readList; /**< Read waiting list */ 58 LOS_DL_LIST writeList; /**< Write waiting list */ 59 } LosRwlock; 60 61 extern BOOL LOS_RwlockIsValid(const LosRwlock *rwlock); 62 63 /** 64 * @ingroup los_rwlock 65 * @brief Init a rwlock. 66 * 67 * @par Description: 68 * This API is used to Init a rwlock. A rwlock handle is assigned to rwlockHandle when the rwlock is init successfully. 69 * Return LOS_OK on creating successful, return specific error code otherwise. 70 * @param rwlock [IN] Handle pointer of the successfully init rwlock. 71 * 72 * @retval #LOS_EINVAL The rwlock pointer is NULL. 73 * @retval #LOS_EPERM Multiply initialization. 74 * @retval #LOS_OK The rwlock is successfully created. 75 * @par Dependency: 76 * <ul><li>los_rwlock.h: the header file that contains the API declaration.</li></ul> 77 * @see LOS_RwlockDestroy 78 */ 79 extern UINT32 LOS_RwlockInit(LosRwlock *rwlock); 80 81 /** 82 * @ingroup los_rwlock 83 * @brief Destroy a rwlock. 84 * 85 * @par Description: 86 * This API is used to delete a specified rwlock. Return LOS_OK on deleting successfully, return specific error code 87 * otherwise. 88 * @attention 89 * <ul> 90 * <li>The specific rwlock should be created firstly.</li> 91 * <li>The rwlock can be deleted successfully only if no other tasks pend on it.</li> 92 * </ul> 93 * 94 * @param rwlock [IN] Handle of the rwlock to be deleted. 95 * 96 * @retval #LOS_EINVAL The rwlock pointer is NULL. 97 * @retval #LOS_EBUSY Tasks pended on this rwlock. 98 * @retval #LOS_EBADF The lock has been destroyed or broken. 99 * @retval #LOS_OK The rwlock is successfully deleted. 100 * @par Dependency: 101 * <ul><li>los_rwlock.h: the header file that contains the API declaration.</li></ul> 102 * @see LOS_RwlockInit 103 */ 104 extern UINT32 LOS_RwlockDestroy(LosRwlock *rwlock); 105 106 /** 107 * @ingroup los_rwlock 108 * @brief Wait to lock a read lock. 109 * 110 * @par Description: 111 * This API is used to wait for a specified period of time to lock a read lock. 112 * @attention 113 * <ul> 114 * <li>The specific rwlock should be created firstly.</li> 115 * <li>The function fails if the rwlock that is waited on is already locked by another thread when the task scheduling 116 * is disabled.</li> 117 * <li>Do not wait on a rwlock during an interrupt.</li> 118 * <li>The function fails when other tasks have the write lock or there are some task pending on the write list with 119 * the higher priority.</li> 120 * <li>A recursive rwlock can be locked more than once by the same thread.</li> 121 * <li>Do not call this API in software timer callback. </li> 122 * </ul> 123 * 124 * @param rwlock [IN] Handle of the rwlock to be waited on. 125 * @param timeout [IN] Waiting time. The value range is [0, LOS_WAIT_FOREVER](unit: Tick). 126 * 127 * @retval #LOS_EINVAL The rwlock pointer is NULL, The timeout is zero or Lock status error. 128 * @retval #LOS_EINTR The rwlock is being locked during an interrupt. 129 * @retval #LOS_EBADF The lock has been destroyed or broken. 130 * @retval #LOS_EDEADLK Rwlock error check failed or System locked task scheduling. 131 * @retval #LOS_ETIMEDOUT The rwlock waiting times out. 132 * @retval #LOS_EPERM The rwlock is used in system tasks. 133 * @retval #LOS_OK The rwlock is successfully locked. 134 * @par Dependency: 135 * <ul><li>los_rwlock.h: the header file that contains the API declaration.</li></ul> 136 * @see LOS_RwlockInit | LOS_RwlockUnLock 137 */ 138 extern UINT32 LOS_RwlockRdLock(LosRwlock *rwlock, UINT32 timeout); 139 140 /** 141 * @ingroup los_rwlock 142 * @brief Try wait to lock a read lock. 143 * 144 * @par Description: 145 * This API is used to wait for a specified period of time to lock a read lock. 146 * @attention 147 * <ul> 148 * <li>The specific rwlock should be created firstly.</li> 149 * <li>The function fails if the rwlock that is waited on is already locked by another thread when the task scheduling 150 * is disabled.</li> 151 * <li>Do not wait on a rwlock during an interrupt.</li> 152 * <li>The function fails when other tasks have the write lock or there are some task pending on the write list with 153 * the higher priority.</li> 154 * <li>A recursive rwlock can be locked more than once by the same thread.</li> 155 * <li>Do not call this API in software timer callback. </li> 156 * </ul> 157 * 158 * @param rwlock [IN] Handle of the rwlock to be waited on. 159 * 160 * @retval #LOS_EINVAL The rwlock pointer is NULL or Lock status error. 161 * @retval #LOS_EINTR The rwlock is being locked during an interrupt. 162 * @retval #LOS_EBUSY Fail to get the rwlock, the rwlock has been used. 163 * @retval #LOS_EBADF The lock has been destroyed or broken. 164 * @retval #LOS_EDEADLK rwlock error check failed or System locked task scheduling. 165 * @retval #LOS_ETIMEDOUT The rwlock waiting times out. 166 * @retval #LOS_EPERM The rwlock is used in system tasks. 167 * @retval #LOS_OK The rwlock is successfully locked. 168 * @par Dependency: 169 * <ul><li>los_rwlock.h: the header file that contains the API declaration.</li></ul> 170 * @see LOS_RwlockInit | LOS_RwlockUnLock 171 */ 172 extern UINT32 LOS_RwlockTryRdLock(LosRwlock *rwlock); 173 174 /** 175 * @ingroup los_rwlock 176 * @brief Wait to lock a write lock. 177 * 178 * @par Description: 179 * This API is used to wait for a specified period of time to lock a write lock. 180 * @attention 181 * <ul> 182 * <li>The specific rwlock should be created firstly.</li> 183 * <li>The function fails if the rwlock that is waited on is already locked by another thread when 184 * the task scheduling.</li> 185 * is disabled.</li> 186 * <li>Do not wait on a rwlock during an interrupt.</li> 187 * <li>The function fails when other tasks have the read or write lock.</li> 188 * <li>A recursive rwlock can be locked more than once by the same thread.</li> 189 * <li>Do not call this API in software timer callback. </li> 190 * </ul> 191 * 192 * @param rwlock [IN] Handle of the rwlock to be waited on. 193 * @param timeout [IN] Waiting time. The value range is [0, LOS_WAIT_FOREVER](unit: Tick). 194 * 195 * @retval #LOS_EINVAL The rwlock pointer is NULL, The timeout is zero or Lock status error. 196 * @retval #LOS_EINTR The rwlock is being locked during an interrupt. 197 * @retval #LOS_EBADF The lock has been destroyed or broken. 198 * @retval #LOS_EDEADLK Rwlock error check failed or System locked task scheduling. 199 * @retval #LOS_ETIMEDOUT The rwlock waiting times out. 200 * @retval #LOS_EPERM The rwlock is used in system tasks. 201 * @retval #LOS_OK The rwlock is successfully locked. 202 * @par Dependency: 203 * <ul><li>los_rwlock.h: the header file that contains the API declaration.</li></ul> 204 * @see LOS_MuxInit | LOS_MuxUnlock 205 */ 206 extern UINT32 LOS_RwlockWrLock(LosRwlock *rwlock, UINT32 timeout); 207 208 /** 209 * @ingroup los_rwlock 210 * @brief Try wait to lock a write lock. 211 * 212 * @par Description: 213 * This API is used to wait for a specified period of time to lock a write lock. 214 * @attention 215 * <ul> 216 * <li>The specific rwlock should be created firstly.</li> 217 * <li>The function fails if the rwlock that is waited on is already locked by another thread 218 * when the task scheduling.</li> 219 * is disabled.</li> 220 * <li>Do not wait on a rwlock during an interrupt.</li> 221 * <li>The function fails when other tasks have the read or write lock.</li> 222 * <li>A recursive rwlock can be locked more than once by the same thread.</li> 223 * <li>Do not call this API in software timer callback. </li> 224 * </ul> 225 * 226 * @param rwlock [IN] Handle of the rwlock to be waited on. 227 * 228 * @retval #LOS_EINVAL The rwlock pointer is NULL or Lock status error. 229 * @retval #LOS_EINTR The rwlock is being locked during an interrupt. 230 * @retval #LOS_EBUSY Fail to get the rwlock, the rwlock has been used. 231 * @retval #LOS_EBADF The lock has been destroyed or broken. 232 * @retval #LOS_EDEADLK rwlock error check failed or System locked task scheduling. 233 * @retval #LOS_ETIMEDOUT The rwlock waiting times out. 234 * @retval #LOS_EPERM The rwlock is used in system tasks. 235 * @retval #LOS_OK The rwlock is successfully locked. 236 * @par Dependency: 237 * <ul><li>los_rwlock.h: the header file that contains the API declaration.</li></ul> 238 * @see LOS_RwlockInit | LOS_RwlockUnLock 239 */ 240 extern UINT32 LOS_RwlockTryWrLock(LosRwlock *rwlock); 241 242 /** 243 * @ingroup los_rwlock 244 * @brief Release a rwlock. 245 * 246 * @par Description: 247 * This API is used to release a specified rwlock. 248 * @attention 249 * <ul> 250 * <li>The specific rwlock should be created firstly.</li> 251 * <li>Do not release a rwlock during an interrupt.</li> 252 * <li>When the write list is null and the read list is not null, all the task pending on the read list 253 * will be waken.<li> 254 * <li>When the write list is not null and the read list is null, the task pending on the read list will be 255 * waken by the priority.<li> 256 * <li>When the write list and the read list are not null, all the task pending on the both list will be waken 257 * by the priority.<li> 258 * If the task on the write list has the same priority as the task on the read list, the forth will 259 * be waken.<li> 260 * <li>If a recursive rwlock is locked for many times, it must be unlocked for the same times to be 261 * released.</li> 262 * </ul> 263 * 264 * @param rwlock [IN] Handle of the rwlock to be released. 265 * 266 * @retval #LOS_EINVAL The rwlock pointer is NULL, The timeout is zero or Lock status error. 267 * @retval #LOS_EINTR The rwlock is being locked during an interrupt. 268 * @retval #LOS_EPERM The rwlock is not locked or has been used. 269 * @retval #LOS_EBADF The lock has been destroyed or broken. 270 * @retval #LOS_EDEADLK rwlock error check failed or System locked task scheduling. 271 * @retval #LOS_ETIMEDOUT The rwlock waiting times out. 272 * @retval #LOS_EPERM The rwlock is used in system tasks. 273 * @retval #LOS_OK The rwlock is successfully locked. 274 * @par Dependency: 275 * <ul><li>los_mux.h: the header file that contains the API declaration.</li></ul> 276 * @see LOS_RwlockInit | LOS_ReadLock | LOS_WriteLock 277 */ 278 extern UINT32 LOS_RwlockUnLock(LosRwlock *rwlock); 279 280 #ifdef __cplusplus 281 #if __cplusplus 282 } 283 #endif 284 #endif /* __cplusplus */ 285 286 #endif /* _LOS_MUX_H */ 287