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_sem Semaphore 34 * @ingroup kernel 35 */ 36 37 #ifndef _LOS_SEM_H 38 #define _LOS_SEM_H 39 40 #include "los_task.h" 41 42 #ifdef __cplusplus 43 #if __cplusplus 44 extern "C" { 45 #endif /* __cplusplus */ 46 #endif /* __cplusplus */ 47 48 /** 49 * @ingroup los_sem 50 * Semaphore error code: The memory is insufficient. 51 * 52 * Value: 0x02000700 53 * 54 * Solution: Allocate more memory. 55 */ 56 #define LOS_ERRNO_SEM_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x00) 57 58 /** 59 * @ingroup los_sem 60 * Semaphore error code: Invalid parameter. 61 * 62 * Value: 0x02000701 63 * 64 * Solution: Change the passed-in invalid parameter value to a valid value. 65 */ 66 #define LOS_ERRNO_SEM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x01) 67 68 /** 69 * @ingroup los_sem 70 * Semaphore error code: Null pointer. 71 * 72 * Value: 0x02000702 73 * 74 * Solution: Change the passed-in null pointer to a valid non-null pointer. 75 */ 76 #define LOS_ERRNO_SEM_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x02) 77 78 /** 79 * @ingroup los_sem 80 * Semaphore error code: No semaphore control structure is available. 81 * 82 * Value: 0x02000703 83 * 84 * Solution: Perform corresponding operations based on the requirements in the code context. 85 */ 86 #define LOS_ERRNO_SEM_ALL_BUSY LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x03) 87 88 /** 89 * @ingroup los_sem 90 * Semaphore error code: Invalid parameter that specifies the timeout interval. 91 * 92 * Value: 0x02000704 93 * 94 * 95 * Solution: Change the passed-in parameter value to a valid nonzero value. 96 */ 97 #define LOS_ERRNO_SEM_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x04) 98 99 /** 100 * @ingroup los_sem 101 * Semaphore error code: The API is called during an interrupt, which is forbidden. 102 * 103 * Value: 0x02000705 104 * 105 * Solution: Do not call the API during an interrupt. 106 */ 107 #define LOS_ERRNO_SEM_PEND_INTERR LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x05) 108 109 /** 110 * @ingroup los_sem 111 * Semaphore error code: The task is unable to request a semaphore because task scheduling is locked. 112 * 113 * Value: 0x02000706 114 * 115 * Solution: Do not call LOS_SemPend when task scheduling is locked. 116 */ 117 #define LOS_ERRNO_SEM_PEND_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x06) 118 119 /** 120 * @ingroup los_sem 121 * Semaphore error code: The request for a semaphore times out. 122 * 123 * Value: 0x02000707 124 * 125 * Solution: Change the passed-in parameter value to the value within the valid range. 126 */ 127 #define LOS_ERRNO_SEM_TIMEOUT LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x07) 128 129 /** 130 * @ingroup los_sem 131 * Semaphore error code: The times of semaphore release exceed the maximum times permitted. 132 * 133 * Value: 0x02000708 134 * 135 * Solution: Perform corresponding operations based on the requirements in the code context. 136 */ 137 #define LOS_ERRNO_SEM_OVERFLOW LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x08) 138 139 /** 140 * @ingroup los_sem 141 * Semaphore error code: The queue of the tasks that are waiting on the semaphore control structure is not null. 142 * 143 * Value: 0x02000709 144 * 145 * Solution: Delete the semaphore after awaking all tasks that are waiting on the semaphore. 146 */ 147 #define LOS_ERRNO_SEM_PENDED LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x09) 148 149 /** 150 * @ingroup los_sem 151 * Semaphore error code: LOS_ERRNO_SEM_MAXNUM_ZERO is error. 152 * 153 * Value: 0x0200070A 154 * 155 * Solution: LOS_ERRNO_SEM_MAXNUM_ZERO should not be error. 156 */ 157 #define LOS_ERRNO_SEM_MAXNUM_ZERO LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x0A) 158 159 /** 160 * @ingroup los_sem 161 * Semaphore error code: The API is called in a system-level task, which is forbidden. 162 * Value: 0x0200070B 163 * 164 * Solution: Do not call the API in system-level tasks. 165 */ 166 #define LOS_ERRNO_SEM_PEND_IN_SYSTEM_TASK LOS_ERRNO_OS_ERROR(LOS_MOD_SEM, 0x0B) 167 168 /** 169 * @ingroup los_sem 170 * @brief Create a Counting semaphore. 171 * 172 * @par Description: 173 * This API is used to create a semaphore control structure according to the initial number of available semaphores 174 * specified by count and return the ID of this semaphore control structure. 175 * @attention 176 * <ul> 177 * <li>None.</li> 178 * </ul> 179 * 180 * @param count [IN] Initial number of available semaphores. The value range is [0, OS_SEM_COUNTING_MAX_COUNT). 181 * @param semHandle [OUT] ID of the semaphore control structure that is initialized. 182 * 183 * @retval #LOS_ERRNO_SEM_PTR_NULL The passed-in semHandle value is NULL. 184 * @retval #LOS_ERRNO_SEM_OVERFLOW The passed-in count value is greater than the maximum number of available 185 * semaphores. 186 * @retval #LOS_ERRNO_SEM_ALL_BUSY No semaphore control structure is available. 187 * @retval #LOS_OK The semaphore is successfully created. 188 * @par Dependency: 189 * <ul><li>los_sem.h: the header file that contains the API declaration.</li></ul> 190 * @see LOS_SemDelete 191 */ 192 extern UINT32 LOS_SemCreate(UINT16 count, UINT32 *semHandle); 193 194 /** 195 * @ingroup los_sem 196 * @brief Create a binary semaphore. 197 * 198 * @par Description: 199 * This API is used to create a binary semaphore control structure according to the initial number of available 200 * semaphores specified by count and return the ID of this semaphore control structure. 201 * @attention 202 * <ul> 203 * <li>None.</li> 204 * </ul> 205 * 206 * @param count [IN] Initial number of available semaphores. The value range is [0, 1]. 207 * @param semHandle [OUT] ID of the semaphore control structure that is initialized. 208 * 209 * @retval #LOS_ERRNO_SEM_PTR_NULL The passed-in semHandle value is NULL. 210 * @retval #LOS_ERRNO_SEM_OVERFLOW The passed-in count value is greater than the maximum number of available 211 * semaphores. 212 * @retval #LOS_ERRNO_SEM_ALL_BUSY No semaphore control structure is available. 213 * @retval #LOS_OK The semaphore is successfully created. 214 * @par Dependency: 215 * <ul><li>los_sem.h: the header file that contains the API declaration.</li></ul> 216 * @see LOS_SemDelete 217 */ 218 extern UINT32 LOS_BinarySemCreate(UINT16 count, UINT32 *semHandle); 219 220 /** 221 * @ingroup los_sem 222 * @brief Delete a semaphore. 223 * 224 * @par Description: 225 * This API is used to delete a semaphore control structure that has an ID specified by semHandle. 226 * @attention 227 * <ul> 228 * <li>The specified sem id must be created first. </li> 229 * </ul> 230 * 231 * @param semHandle [IN] ID of the semaphore control structure to be deleted. The ID of the semaphore 232 * control structure is obtained from semaphore creation. 233 * 234 * @retval #LOS_ERRNO_SEM_INVALID The passed-in semHandle value is invalid. 235 * @retval #LOS_ERRNO_SEM_PENDED The queue of the tasks that are waiting on the semaphore control structure is 236 * not null. 237 * @retval #LOS_OK The semaphore control structure is successfully deleted. 238 * @par Dependency: 239 * <ul><li>los_sem.h: the header file that contains the API declaration.</li></ul> 240 * @see LOS_SemCreate 241 */ 242 extern UINT32 LOS_SemDelete(UINT32 semHandle); 243 244 /** 245 * @ingroup los_sem 246 * @brief Request a semaphore. 247 * 248 * @par Description: 249 * This API is used to request a semaphore based on the semaphore control structure ID specified by semHandle and the 250 * parameter that specifies the timeout period. 251 * @attention 252 * <ul> 253 * <li>The specified sem id must be created first. </li> 254 * </ul> 255 * 256 * @param semHandle [IN] ID of the semaphore control structure to be requested. The ID of the semaphore control 257 * structure is obtained from semaphore creation. 258 * @param timeout [IN] Timeout interval for waiting on the semaphore. The value range is [0, 0xFFFFFFFF]. 259 * If the value is set to 0, the semaphore is not waited on. If the value is set to 0xFFFFFFFF, 260 * the semaphore is waited on forever(unit: Tick). 261 * 262 * @retval #LOS_ERRNO_SEM_INVALID The passed-in semHandle value is invalid. 263 * @retval #LOS_ERRNO_SEM_UNAVAILABLE There is no available semaphore resource. 264 * @retval #LOS_ERRNO_SEM_PEND_INTERR The API is called during an interrupt, which is forbidden. 265 * @retval #LOS_ERRNO_SEM_PEND_IN_LOCK The task is unable to request a semaphore because task scheduling is locked. 266 * @retval #LOS_ERRNO_SEM_TIMEOUT The request for the semaphore times out. 267 * @retval #LOS_OK The semaphore request succeeds. 268 * @par Dependency: 269 * <ul><li>los_sem.h: the header file that contains the API declaration.</li></ul> 270 * @see LOS_SemPost | LOS_SemCreate 271 */ 272 extern UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout); 273 274 /** 275 * @ingroup los_sem 276 * @brief Release a semaphore. 277 * 278 * @par Description: 279 * This API is used to release a semaphore that has a semaphore control structure ID specified by semHandle. 280 * @attention 281 * <ul> 282 * <li>The specified sem id must be created first. </li> 283 * </ul> 284 * 285 * @param semHandle [IN] ID of the semaphore control structure to be released.The ID of the semaphore control 286 * structure is obtained from semaphore creation. 287 * 288 * @retval #LOS_ERRNO_SEM_INVALID The passed-in semHandle value is invalid. 289 * @retval #LOS_ERRNO_SEM_OVERFLOW The times of semaphore release exceed the maximum times permitted. 290 * @retval #LOS_OK The semaphore is successfully released. 291 * @par Dependency: 292 * <ul><li>los_sem.h: the header file that contains the API declaration.</li></ul> 293 * @see LOS_SemPend | LOS_SemCreate 294 */ 295 extern UINT32 LOS_SemPost(UINT32 semHandle); 296 297 extern UINT32 LOS_SemGetValue(UINT32 semHandle, INT32 *currVal); 298 299 /** 300 * @ingroup los_sem 301 * Semaphore control structure. 302 */ 303 typedef struct { 304 UINT16 semStat; /**< Semaphore state */ 305 UINT16 semCount; /**< Number of available semaphores */ 306 UINT16 maxSemCount; /**< Max number of available semaphores */ 307 UINT16 semID; /**< Semaphore control structure ID */ 308 LOS_DL_LIST semList; /**< Queue of tasks that are waiting on a semaphore */ 309 } LosSemCB; 310 311 /** 312 * @ingroup los_config 313 * Max count of binary semaphores. 314 */ 315 #define OS_SEM_BINARY_MAX_COUNT 1 316 317 /** 318 * @ingroup los_sem 319 * The semaphore is not in use. 320 */ 321 #define OS_SEM_UNUSED 0 322 323 /** 324 * @ingroup los_sem 325 * The semaphore is used. 326 */ 327 #define OS_SEM_USED 1 328 329 /** 330 * @ingroup los_sem 331 * Obtain the head node in a semaphore doubly linked list. 332 */ 333 #define GET_SEM_LIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosSemCB, semList) 334 335 extern LosSemCB *g_allSem; 336 /** 337 * @ingroup los_sem 338 * Obtain a semaphore ID. 339 * 340 */ 341 #define GET_SEM(semid) (((LosSemCB *)g_allSem) + (semid)) 342 343 /** 344 * @ingroup los_sem 345 * @brief Initialize the Semaphore doubly linked list. 346 * 347 * @par Description: 348 * This API is used to initialize the Semaphore doubly linked list. 349 * @attention 350 * <ul> 351 * <li>None.</li> 352 * </ul> 353 * 354 * @param None. 355 * 356 * @retval UINT32 Initialization result. 357 * @par Dependency: 358 * <ul><li>los_sem.h: the header file that contains the API declaration.</li></ul> 359 * @see None. 360 */ 361 extern UINT32 OsSemInit(VOID); 362 363 /** 364 * @ingroup los_sem 365 * @brief Create Semaphore. 366 * 367 * @par Description: 368 * This API is used to create Semaphore. 369 * @attention 370 * <ul> 371 * <li>None.</li> 372 * </ul> 373 * 374 * @param count [IN]Type #UINT16 Semaphore count. 375 * @param maxCount [IN]Type #UINT16 Max semaphore count. 376 * @param semHandle [OUT]Type #UINT32 * Index of semaphore. 377 * 378 * @retval UINT32 Create result. 379 * @par Dependency: 380 * <ul><li>los_sem.h: the header file that contains the API declaration.</li></ul> 381 * @see None. 382 */ 383 UINT32 OsSemCreate(UINT16 count, UINT16 maxCount, UINT32 *semHandle); 384 385 #ifdef __cplusplus 386 #if __cplusplus 387 } 388 #endif /* __cplusplus */ 389 #endif /* __cplusplus */ 390 391 #endif /* _LOS_SEM_H */ 392