• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }