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
MapError(UINT32 err)43 static 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
sem_init(sem_t * sem,int shared,unsigned int value)68 int 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
sem_destroy(sem_t * sem)91 int 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
sem_wait(sem_t * sem)109 int 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
sem_post(sem_t * sem)127 int 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
sem_trywait(sem_t * sem)145 int 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
sem_timedwait(sem_t * sem,const struct timespec * timeout)163 int 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
sem_getvalue(sem_t * sem,int * currVal)192 int 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 }