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