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#include <stdint.h> 33#include <semaphore.h> 34#include <errno.h> 35#include "los_sem.h" 36#include "time_internal.h" 37 38#define _SEM_MAGIC 0xEBCFDEA1 39 40#define s_magic __val[0] 41#define s_handle __val[1] 42 43static inline int MapError(UINT32 err) 44{ 45 switch (err) { 46 case LOS_OK: 47 return 0; 48 case LOS_ERRNO_SEM_INVALID: 49 case LOS_ERRNO_SEM_UNAVAILABLE: 50 return EINVAL; 51 case LOS_ERRNO_SEM_ALL_BUSY: 52 return ENOSPC; 53 case LOS_ERRNO_SEM_OVERFLOW: 54 return ENOMEM; 55 case LOS_ERRNO_SEM_PENDED: 56 return EBUSY; 57 case LOS_ERRNO_SEM_PEND_IN_LOCK: 58 return EPERM; 59 case LOS_ERRNO_SEM_PEND_INTERR: 60 return EINTR; 61 case LOS_ERRNO_SEM_TIMEOUT: 62 return ETIMEDOUT; 63 default: 64 return EINVAL; 65 } 66} 67 68int sem_init(sem_t *sem, int shared, unsigned int value) 69{ 70 UINT32 semHandle = 0; 71 UINT32 ret; 72 73 (VOID)shared; 74 if ((sem == NULL) || (value >= OS_SEM_COUNTING_MAX_COUNT)) { 75 errno = EINVAL; 76 return -1; 77 } 78 79 ret = LOS_SemCreate(value, &semHandle); 80 if (ret != LOS_OK) { 81 errno = MapError(ret); 82 return -1; 83 } 84 85 sem->s_magic = (INT32)_SEM_MAGIC; 86 sem->s_handle = (INT32)semHandle; 87 88 return 0; 89} 90 91int sem_destroy(sem_t *sem) 92{ 93 UINT32 ret; 94 95 if ((sem == NULL) || (sem->s_magic != (INT32)_SEM_MAGIC)) { 96 errno = EINVAL; 97 return -1; 98 } 99 100 ret = LOS_SemDelete((UINT32)sem->s_handle); 101 if (ret != LOS_OK) { 102 errno = MapError(ret); 103 return -1; 104 } 105 106 return 0; 107} 108 109int sem_wait(sem_t *sem) 110{ 111 UINT32 ret; 112 113 if ((sem == NULL) || (sem->s_magic != (INT32)_SEM_MAGIC)) { 114 errno = EINVAL; 115 return -1; 116 } 117 118 ret = LOS_SemPend((UINT32)sem->s_handle, LOS_WAIT_FOREVER); 119 if (ret != LOS_OK) { 120 errno = MapError(ret); 121 return -1; 122 } 123 124 return 0; 125} 126 127int sem_post(sem_t *sem) 128{ 129 UINT32 ret; 130 131 if ((sem == NULL) || (sem->s_magic != (INT32)_SEM_MAGIC)) { 132 errno = EINVAL; 133 return -1; 134 } 135 136 ret = LOS_SemPost((UINT32)sem->s_handle); 137 if (ret != LOS_OK) { 138 errno = MapError(ret); 139 return -1; 140 } 141 142 return 0; 143} 144 145int sem_trywait(sem_t *sem) 146{ 147 UINT32 ret; 148 149 if ((sem == NULL) || (sem->s_magic != (INT32)_SEM_MAGIC)) { 150 errno = EINVAL; 151 return -1; 152 } 153 154 ret = LOS_SemPend((UINT32)sem->s_handle, LOS_NO_WAIT); 155 if (ret != LOS_OK) { 156 errno = MapError(ret); 157 return -1; 158 } 159 160 return 0; 161} 162 163int sem_timedwait(sem_t *sem, const struct timespec *timeout) 164{ 165 UINT32 ret; 166 UINT64 tickCnt; 167 168 if ((sem == NULL) || (sem->s_magic != (INT32)_SEM_MAGIC)) { 169 errno = EINVAL; 170 return -1; 171 } 172 173 ret = OsGetTickTimeFromNow(timeout, CLOCK_REALTIME, &tickCnt); 174 if (ret != 0) { 175 errno = (INT32)ret; 176 return -1; 177 } 178 179 if (tickCnt > LOS_WAIT_FOREVER) { 180 tickCnt = LOS_WAIT_FOREVER; 181 } 182 183 ret = LOS_SemPend((UINT32)sem->s_handle, (UINT32)tickCnt); 184 if (ret != LOS_OK) { 185 errno = MapError(ret); 186 return -1; 187 } 188 189 return 0; 190} 191 192int sem_getvalue(sem_t *sem, int *currVal) 193{ 194 UINT32 ret; 195 196 if ((sem == NULL) || (sem->s_magic != (INT32)_SEM_MAGIC)|| (currVal == NULL)) { 197 errno = EINVAL; 198 return -1; 199 } 200 201 ret = LOS_SemGetValue(sem->s_handle, currVal); 202 if (ret) { 203 errno = EINVAL; 204 return -1; 205 } 206 207 return LOS_OK; 208}