• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved.
3  *
4  * UniProton is licensed under Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *          http://license.coscl.org.cn/MulanPSL2
8  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11  * See the Mulan PSL v2 for more details.
12  * Create: 2022-11-15
13  * Description: posix sem功能实现
14  */
15 #include "semaphore.h"
16 #include "prt_posix_internal.h"
17 #include "prt_sem_external.h"
18 #include "prt_sem.h"
19 #include "prt_sys_external.h"
20 
sem_init(sem_t * sem,int shared,unsigned int value)21 int sem_init(sem_t *sem, int shared, unsigned int value)
22 {
23     U32 ret;
24     uintptr_t intSave;
25     SemHandle semHandle;
26     struct TagSemCb *semCb;
27 
28     (void)shared;
29     if (sem == NULL) {
30         errno = EINVAL;
31         return PTHREAD_OP_FAIL;
32     }
33     if (value > OS_SEM_COUNT_MAX) {
34         errno = EINVAL;
35         return PTHREAD_OP_FAIL;
36     }
37 
38     intSave = OsIntLock();
39 
40     ret = PRT_SemCreate(value, &semHandle);
41     if (ret != OS_OK) {
42         OsIntRestore(intSave);
43         errno = EINVAL;
44         return PTHREAD_OP_FAIL;
45     }
46 
47     // 创建成功
48     semCb = GET_SEM(semHandle);
49     snprintf_s(semCb->name, MAX_POSIX_SEMAPHORE_NAME_LEN + 1, MAX_POSIX_SEMAPHORE_NAME_LEN, "defaultSem%d", semHandle);
50     sem->refCount++;
51     sem->semHandle = semHandle;
52     OsIntRestore(intSave);
53 
54     return OS_OK;
55 }
56 
sem_open(const char * name,int flags,...)57 sem_t *sem_open(const char *name, int flags, ...)
58 {
59     U32 i;
60     U32 ret;
61     U32 val;
62     int mode;
63     va_list arg;
64     uintptr_t intSave;
65     struct TagSemCb *semCb;
66     bool created = FALSE;
67     SemHandle sem;
68 
69     if (name == NULL) {
70         errno = EINVAL;
71         return SEM_FAILED;
72     }
73 
74     if (strlen(name) >= MAX_POSIX_SEMAPHORE_NAME_LEN) {
75         errno = EINVAL;
76         return SEM_FAILED;
77     }
78 
79     va_start(arg, flags);
80     mode = (int)va_arg(arg, unsigned int);
81     val = va_arg(arg, unsigned int);
82     va_end(arg);
83     (void)mode;
84     intSave = PRT_HwiLock();
85     for (i = 0; i < g_maxSem; i++) {
86         semCb = GET_SEM(i);
87         if (strcmp((const char *)semCb->name, name) == 0) {
88             created = TRUE;
89             break;
90         }
91     }
92 
93     if (created == TRUE) {
94         if (((U32)flags & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT)) {
95             PRT_HwiRestore(intSave);
96             errno = EEXIST;
97             return SEM_FAILED;
98         }
99         semCb->handle.refCount++;
100         PRT_HwiRestore(intSave);
101         return (sem_t *)&(semCb->handle);
102     }
103     if ((flags & O_CREAT) == 0) {
104         PRT_HwiRestore(intSave);
105         errno = ENOENT;
106         return SEM_FAILED;
107     }
108     if (val > OS_SEM_COUNT_MAX) {
109         PRT_HwiRestore(intSave);
110         errno = EINVAL;
111         return SEM_FAILED;
112     }
113 
114     ret = PRT_SemCreate(val, &sem);
115     if (ret != OS_OK) {
116         PRT_HwiRestore(intSave);
117         errno = EAGAIN;
118         return SEM_FAILED;
119     }
120 
121     semCb = GET_SEM(sem);
122     if (strncpy_s((char *)semCb->name, MAX_POSIX_SEMAPHORE_NAME_LEN + 1, name, strlen(name) + 1) != 0) {
123         OS_GOTO_SYS_ERROR1();
124     }
125 
126     semCb->handle.semHandle = sem;
127     semCb->handle.refCount++;
128     PRT_HwiRestore(intSave);
129 
130     return (sem_t *)&(semCb->handle);
131 }
132 
sem_close(sem_t * sem)133 int sem_close(sem_t *sem)
134 {
135     uintptr_t intSave;
136     struct TagSemCb *semCb;
137 
138     if (sem == NULL) {
139         errno = EINVAL;
140         return PTHREAD_OP_FAIL;
141     }
142 
143     semCb = GET_SEM(sem->semHandle);
144 
145     intSave = PRT_HwiLock();
146     if (semCb->name[0] == 0) {
147         PRT_HwiRestore(intSave);
148         return OS_OK;
149     }
150 
151     if (semCb->handle.refCount > 0) {
152         semCb->handle.refCount--;
153     } else {
154         PRT_HwiRestore(intSave);
155         errno = EINVAL;
156         return PTHREAD_OP_FAIL;
157     }
158 
159     PRT_HwiRestore(intSave);
160     return OS_OK;
161 }
162 
sem_getvalue(sem_t * __restrict sem,int * __restrict val)163 int sem_getvalue(sem_t *__restrict sem, int *__restrict val)
164 {
165     U32 ret;
166     uintptr_t intSave;
167     struct TagSemCb *semCb;
168 
169     if (val == NULL || sem == NULL) {
170         errno = EINVAL;
171         return PTHREAD_OP_FAIL;
172     }
173 
174     semCb = GET_SEM(sem->semHandle);
175     intSave = PRT_HwiLock();
176     if (semCb->name[0] == 0) {
177         PRT_HwiRestore(intSave);
178         errno = EINVAL;
179         return PTHREAD_OP_FAIL;
180     }
181     ret = PRT_SemGetCount(sem->semHandle, (U32 *)val);
182     if (ret != OS_OK) {
183         PRT_HwiRestore(intSave);
184         errno = EINVAL;
185         return PTHREAD_OP_FAIL;
186     }
187     PRT_HwiRestore(intSave);
188 
189     return OS_OK;
190 }
191 
sem_wait(sem_t * sem)192 int sem_wait(sem_t *sem)
193 {
194     U32 ret;
195     uintptr_t intSave;
196     struct TagSemCb *semCb;
197 
198     if (sem == NULL) {
199         errno = EINVAL;
200         return PTHREAD_OP_FAIL;
201     }
202     semCb = GET_SEM(sem->semHandle);
203     intSave = PRT_HwiLock();
204     if (semCb->name[0] == 0) {
205         PRT_HwiRestore(intSave);
206         errno = EINVAL;
207         return PTHREAD_OP_FAIL;
208     }
209 
210     ret = PRT_SemPend(sem->semHandle, OS_WAIT_FOREVER);
211     if (ret != OS_OK) {
212         PRT_HwiRestore(intSave);
213         errno = EINVAL;
214         return PTHREAD_OP_FAIL;
215     }
216     PRT_HwiRestore(intSave);
217 
218     return OS_OK;
219 }
220 
sem_trywait(sem_t * sem)221 int sem_trywait(sem_t *sem)
222 {
223     U32 ret;
224     uintptr_t intSave;
225     struct TagSemCb *semCb;
226 
227     if (sem == NULL) {
228         errno = EINVAL;
229         return PTHREAD_OP_FAIL;
230     }
231     semCb = GET_SEM(sem->semHandle);
232     intSave = PRT_HwiLock();
233     if (semCb->name[0] == 0) {
234         PRT_HwiRestore(intSave);
235         errno = EINVAL;
236         return PTHREAD_OP_FAIL;
237     }
238 
239     ret = PRT_SemPend(sem->semHandle, 0);
240     if (ret != OS_OK) {
241         PRT_HwiRestore(intSave);
242         errno = EAGAIN;
243         return PTHREAD_OP_FAIL;
244     }
245     PRT_HwiRestore(intSave);
246 
247     return OS_OK;
248 }
249 
sem_timedwait(sem_t * __restrict sem,const struct timespec * __restrict at)250 int sem_timedwait(sem_t *__restrict sem, const struct timespec *__restrict at)
251 {
252     U32 ret;
253     U32 ticks;
254 
255     if (at == NULL || sem == NULL) {
256         errno = EINVAL;
257         return PTHREAD_OP_FAIL;
258     }
259     if ((at->tv_sec < 0) || (at->tv_nsec < 0) || (at->tv_nsec > OS_SYS_NS_PER_SECOND)) {
260         errno = EINVAL;
261         return PTHREAD_OP_FAIL;
262     }
263 
264     ret = OsTimeOut2Ticks(at, &ticks);
265     if (ret != OS_OK) {
266         errno = EINVAL;
267         return PTHREAD_OP_FAIL;
268     }
269     ret = PRT_SemPend(sem->semHandle, ticks);
270     if (ret == OS_ERRNO_SEM_TIMEOUT) {
271         errno = ETIMEDOUT;
272         return PTHREAD_OP_FAIL;
273     } else if (ret != OS_OK) {
274         errno = EINVAL;
275         return PTHREAD_OP_FAIL;
276     }
277 
278     return OS_OK;
279 }
280 
sem_post(sem_t * sem)281 int sem_post(sem_t *sem)
282 {
283     U32 ret;
284     uintptr_t intSave;
285     struct TagSemCb *semCb;
286 
287     if (sem == NULL) {
288         errno = EINVAL;
289         return PTHREAD_OP_FAIL;
290     }
291     semCb = GET_SEM(sem->semHandle);
292 
293     intSave = PRT_HwiLock();
294     if (semCb->name[0] == 0) {
295         PRT_HwiRestore(intSave);
296         errno = EINVAL;
297         return PTHREAD_OP_FAIL;
298     }
299 
300     ret = PRT_SemPost(sem->semHandle);
301     if (ret != OS_OK) {
302         PRT_HwiRestore(intSave);
303         errno = EINVAL;
304         return PTHREAD_OP_FAIL;
305     }
306     PRT_HwiRestore(intSave);
307 
308     return OS_OK;
309 }
310 
sem_destroy(sem_t * sem)311 int sem_destroy(sem_t *sem)
312 {
313     U32 ret;
314     struct TagSemCb *semCb;
315 
316     if (sem == NULL) {
317         errno = EINVAL;
318         return PTHREAD_OP_FAIL;
319     }
320     semCb = GET_SEM(sem->semHandle);
321 
322     ret = PRT_SemDelete(sem->semHandle);
323     if (ret != OS_OK) {
324         errno = EINVAL;
325         return PTHREAD_OP_FAIL;
326     }
327 
328     (void)memset_s(semCb->name, MAX_POSIX_SEMAPHORE_NAME_LEN + 1, 0, MAX_POSIX_SEMAPHORE_NAME_LEN + 1);
329     sem->semHandle = 0xffffU;
330     sem->refCount = 0;
331 
332     return OS_OK;
333 }
334 
sem_unlink(const char * name)335 int sem_unlink(const char *name)
336 {
337     U32 i;
338     uintptr_t intSave;
339     struct TagSemCb *semCb;
340     bool find = FALSE;
341     U32 ret = OS_OK;
342 
343     if (name == NULL) {
344         errno = EINVAL;
345         return PTHREAD_OP_FAIL;
346     }
347     intSave = PRT_HwiLock();
348     for (i = 0; i < g_maxSem; i++) {
349         semCb = GET_SEM(i);
350         if (strcmp((const char *)semCb->name, name) == 0) {
351             find = TRUE;
352             break;
353         }
354     }
355     if (find == FALSE) {
356         PRT_HwiRestore(intSave);
357         errno = EINVAL;
358         return PTHREAD_OP_FAIL;
359     }
360 
361     if (semCb->handle.refCount == 0) {
362         ret = PRT_SemDelete((SemHandle)i);
363         if (ret != OS_OK) {
364             PRT_HwiRestore(intSave);
365             errno = EINVAL;
366             return PTHREAD_OP_FAIL;
367         }
368     }
369 
370     (void)memset_s(semCb->name, MAX_POSIX_SEMAPHORE_NAME_LEN + 1, 0, MAX_POSIX_SEMAPHORE_NAME_LEN + 1);
371     semCb->handle.refCount = 0;
372     PRT_HwiRestore(intSave);
373 
374     return OS_OK;
375 }
376