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 /** 33 * @defgroup los_mux Mutex 34 * @ingroup kernel 35 */ 36 37 #ifndef _LOS_MUX_H 38 #define _LOS_MUX_H 39 40 #include "los_task.h" 41 42 43 #ifdef __cplusplus 44 #if __cplusplus 45 extern "C" { 46 #endif /* __cplusplus */ 47 #endif /* __cplusplus */ 48 49 /** 50 * @ingroup los_mux 51 * Mutex error code: The memory request fails. 52 * 53 * Value: 0x02001d00 54 * 55 * Solution: Decrease the number of mutexes defined by LOSCFG_BASE_IPC_MUX_LIMIT. 56 */ 57 #define LOS_ERRNO_MUX_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x00) 58 59 /** 60 * @ingroup los_mux 61 * Mutex error code: The mutex is not usable. 62 * 63 * Value: 0x02001d01 64 * 65 * Solution: Check whether the mutex ID and the mutex state are applicable for the current operation. 66 */ 67 #define LOS_ERRNO_MUX_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x01) 68 69 /** 70 * @ingroup los_mux 71 * Mutex error code: Null pointer. 72 * 73 * Value: 0x02001d02 74 * 75 * Solution: Check whether the input parameter is usable. 76 */ 77 #define LOS_ERRNO_MUX_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x02) 78 79 /** 80 * @ingroup los_mux 81 * Mutex error code: No mutex is available and the mutex request fails. 82 * 83 * Value: 0x02001d03 84 * 85 * Solution: Increase the number of mutexes defined by LOSCFG_BASE_IPC_MUX_LIMIT. 86 */ 87 #define LOS_ERRNO_MUX_ALL_BUSY LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x03) 88 89 /** 90 * @ingroup los_mux 91 * Mutex error code: The mutex fails to be locked in non-blocking mode because it is locked by another thread. 92 * 93 * Value: 0x02001d04 94 * 95 * Solution: Lock the mutex after it is unlocked by the thread that owns it, or set a waiting time. 96 */ 97 #define LOS_ERRNO_MUX_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x04) 98 99 /** 100 * @ingroup los_mux 101 * Mutex error code: The mutex is being locked during an interrupt. 102 * 103 * Value: 0x02001d05 104 * 105 * Solution: Check whether the mutex is being locked during an interrupt. 106 */ 107 #define LOS_ERRNO_MUX_IN_INTERR LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x05) 108 109 /** 110 * @ingroup los_mux 111 * Mutex error code: A thread locks a mutex after waiting for the mutex to be unlocked by another thread 112 * when the task scheduling is disabled. 113 * 114 * Value: 0x02001d06 115 * 116 * Solution: Check whether the task scheduling is disabled, or set uwtimeout to 0, which means that the 117 * thread will not wait for the mutex to become available. 118 */ 119 #define LOS_ERRNO_MUX_PEND_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x06) 120 121 /** 122 * @ingroup los_mux 123 * Mutex error code: The mutex locking times out. 124 * 125 * Value: 0x02001d07 126 * 127 * Solution: Increase the waiting time or set the waiting time to LOS_WAIT_FOREVER (forever-blocking mode). 128 */ 129 #define LOS_ERRNO_MUX_TIMEOUT LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x07) 130 131 /** 132 * @ingroup los_mux 133 * 134 * Value: 0x02001d08 135 * Not in use temporarily. 136 */ 137 #define LOS_ERRNO_MUX_OVERFLOW LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x08) 138 139 /** 140 * @ingroup los_mux 141 * Mutex error code: The mutex to be deleted is being locked. 142 * 143 * Value: 0x02001d09 144 * 145 * Solution: Delete the mutex after it is unlocked. 146 */ 147 #define LOS_ERRNO_MUX_PENDED LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x09) 148 149 /** 150 * @ingroup los_mux 151 * 152 * Value: 0x02001d0A 153 * Not in use temporarily. 154 */ 155 #define LOS_ERRNO_MUX_GET_COUNT_ERR LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x0A) 156 157 /** 158 * @ingroup los_mux 159 * 160 * Value: 0x02001d0B 161 * Not in use temporarily. 162 */ 163 #define LOS_ERRNO_MUX_REG_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x0B) 164 165 /** 166 * @ingroup los_mux 167 * 168 * Mutex error code: LOS_ERRNO_MUX_MAXNUM_ZERO is zero. 169 * Value: 0x02001d0C 170 * 171 * Solution: LOS_ERRNO_MUX_MAXNUM_ZERO should not be zero. 172 */ 173 #define LOS_ERRNO_MUX_MAXNUM_ZERO LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x0C) 174 175 /** 176 * @ingroup los_mux 177 * 178 * Mutex error code: The API is called in a system-level task, which is forbidden. 179 * Value: 0x02001d0D 180 * 181 * Solution: Do not call the API in system-level tasks. 182 */ 183 #define LOS_ERRNO_MUX_PEND_IN_SYSTEM_TASK LOS_ERRNO_OS_ERROR(LOS_MOD_MUX, 0x0D) 184 185 /** 186 * @ingroup los_mux 187 * @brief Create a mutex. 188 * 189 * @par Description: 190 * This API is used to create a mutex. A mutex handle is assigned to muxHandle when the mutex is created successfully. 191 * Return LOS_OK on creating successful, return specific error code otherwise. 192 * @attention 193 * <ul> 194 * <li>The total number of mutexes is pre-configured. If there are no available mutexes, the mutex creation fails.</li> 195 * </ul> 196 * 197 * @param muxHandle [OUT] Handle pointer of the successfully created mutex. The value of handle should be in 198 * [0, LOSCFG_BASE_IPC_MUX_LIMIT - 1]. 199 * 200 * @retval #LOS_ERRNO_MUX_PTR_NULL The muxHandle pointer is NULL. 201 * @retval #LOS_ERRNO_MUX_ALL_BUSY No available mutex. 202 * @retval #LOS_OK The mutex is successfully created. 203 * @par Dependency: 204 * <ul><li>los_mux.h: the header file that contains the API declaration.</li></ul> 205 * @see LOS_MuxDelete 206 */ 207 extern UINT32 LOS_MuxCreate(UINT32 *muxHandle); 208 209 /** 210 * @ingroup los_mux 211 * @brief Delete a mutex. 212 * 213 * @par Description: 214 * This API is used to delete a specified mutex. Return LOS_OK on deleting successfully, return specific error code 215 * otherwise. 216 * @attention 217 * <ul> 218 * <li>The specific mutex should be created firstly.</li> 219 * <li>The mutex can be deleted successfully only if no other tasks pend on it.</li> 220 * </ul> 221 * 222 * @param muxHandle [IN] Handle of the mutex to be deleted. The value of handle should be in 223 * [0, LOSCFG_BASE_IPC_MUX_LIMIT - 1]. 224 * 225 * @retval #LOS_ERRNO_MUX_INVALID Invalid handle or mutex in use. 226 * @retval #LOS_ERRNO_MUX_PENDED Tasks pended on this mutex. 227 * @retval #LOS_OK The mutex is successfully deleted. 228 * @par Dependency: 229 * <ul><li>los_mux.h: the header file that contains the API declaration.</li></ul> 230 * @see LOS_MuxCreate 231 */ 232 extern UINT32 LOS_MuxDelete(UINT32 muxHandle); 233 234 /** 235 * @ingroup los_mux 236 * @brief Wait to lock a mutex. 237 * 238 * @par Description: 239 * This API is used to wait for a specified period of time to lock a mutex. 240 * @attention 241 * <ul> 242 * <li>The specific mutex should be created firstly.</li> 243 * <li>The function fails if the mutex that is waited on is already locked by another thread when the task scheduling 244 * is disabled.</li> 245 * <li>Do not wait on a mutex during an interrupt.</li> 246 * <li>The priority inheritance protocol is supported. If a higher-priority thread is waiting on a mutex, it changes 247 * the priority of the thread that owns the mutex to avoid priority inversion.</li> 248 * <li>A recursive mutex can be locked more than once by the same thread.</li> 249 * </ul> 250 * 251 * @param muxHandle [IN] Handle of the mutex to be waited on. The value of handle should be 252 * in [0, LOSCFG_BASE_IPC_MUX_LIMIT - 1]. 253 * @param timeout [IN] Waiting time. The value range is [0, LOS_WAIT_FOREVER](unit: Tick). 254 * 255 * @retval #LOS_ERRNO_MUX_INVALID The mutex state (for example, the mutex does not exist or is not in use) 256 * is not applicable for the current operation. 257 * @retval #LOS_ERRNO_MUX_UNAVAILABLE The mutex fails to be locked because it is locked by another thread and 258 * a period of time is not set for waiting for the mutex to become available. 259 * @retval #LOS_ERRNO_MUX_IN_INTERR The mutex is being locked during an interrupt. 260 * @retval #LOS_ERRNO_MUX_PEND_IN_LOCK The mutex is waited on when the task scheduling is disabled. 261 * @retval #LOS_ERRNO_MUX_TIMEOUT The mutex waiting times out. 262 * @retval #LOS_OK The mutex is successfully locked. 263 * @par Dependency: 264 * <ul><li>los_mux.h: the header file that contains the API declaration.</li></ul> 265 * @see LOS_MuxCreate | LOS_MuxPost 266 */ 267 extern UINT32 LOS_MuxPend(UINT32 muxHandle, UINT32 timeout); 268 269 /** 270 * @ingroup los_mux 271 * @brief Release a mutex. 272 * 273 * @par Description: 274 * This API is used to release a specified mutex. 275 * @attention 276 * <ul> 277 * <li>The specific mutex should be created firstly.</li> 278 * <li>Do not release a mutex during an interrupt.</li> 279 * <li>If a recursive mutex is locked for many times, it must be unlocked for the same times to be released.</li> 280 * </ul> 281 * 282 * @param muxHandle [IN] Handle of the mutex to be released. The value of handle should be in 283 * [0, LOSCFG_BASE_IPC_MUX_LIMIT - 1]. 284 * 285 * @retval #LOS_ERRNO_MUX_INVALID The mutex state (for example, the mutex does not exist or is not in use 286 * or owned by other thread) is not applicable for the current operation. 287 * @retval #LOS_ERRNO_MUX_IN_INTERR The mutex is being released during an interrupt. 288 * @retval #LOS_OK The mutex is successfully released. 289 * @par Dependency: 290 * <ul><li>los_mux.h: the header file that contains the API declaration.</li></ul> 291 * @see LOS_MuxCreate | LOS_MuxPend 292 */ 293 extern UINT32 LOS_MuxPost(UINT32 muxHandle); 294 295 /** 296 * @ingroup los_mux 297 * Mutex object. 298 */ 299 typedef struct { 300 UINT8 muxStat; /**< State OS_MUX_UNUSED,OS_MUX_USED */ 301 UINT16 muxCount; /**< Times of locking a mutex */ 302 UINT32 muxID; /**< Handle ID */ 303 LOS_DL_LIST muxList; /**< Mutex linked list */ 304 LosTaskCB *owner; /**< The current thread that is locking a mutex */ 305 UINT16 priority; /**< Priority of the thread that is locking a mutex */ 306 } LosMuxCB; 307 308 /** 309 * @ingroup los_mux 310 * Mutex state: not in use. 311 */ 312 #define OS_MUX_UNUSED 0 313 314 /** 315 * @ingroup los_mux 316 * Mutex state: in use. 317 */ 318 #define OS_MUX_USED 1 319 320 extern LosMuxCB *g_allMux; 321 322 /** 323 * @ingroup los_mux 324 * Obtain the pointer to a mutex object of the mutex that has a specified handle. 325 */ 326 #define GET_MUX(muxid) (((LosMuxCB *)g_allMux) + (muxid)) 327 328 /** 329 * @ingroup los_mux 330 * @brief Initializes the mutex. 331 * 332 * @par Description: 333 * This API is used to initializes the mutex. 334 * @attention 335 * <ul> 336 * <li>None.</li> 337 * </ul> 338 * 339 * @param None. 340 * 341 * @retval UINT32 Initialization result. 342 * @par Dependency: 343 * <ul><li>los_mux.h: the header file that contains the API declaration.</li></ul> 344 * @see LOS_MuxDelete 345 */ 346 extern UINT32 OsMuxInit(VOID); 347 348 /** 349 * @ingroup los_mux 350 * Obtain the pointer to the linked list in the mutex pointed to by a specified pointer. 351 */ 352 #define GET_MUX_LIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosMuxCB, muxList) 353 354 #ifdef __cplusplus 355 #if __cplusplus 356 } 357 #endif 358 #endif /* __cplusplus */ 359 360 #endif /* _LOS_MUX_H */ 361