• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "napi/native_api.h"
17 #include <cstdlib>
18 #include <ctime>
19 #include <pthread.h>
20 #include <semaphore.h>
21 #include <sys/resource.h>
22 #include <threads.h>
23 #include <unistd.h>
24 
25 #define TEST_RESULT_PASSED 0
26 #define TEST_RESULT_FAILED (-1)
27 #define PARAM_5 5
28 #define PARAM_0 0
29 #define PARAM_1 1
30 #define PARAM_2 2
31 #define PARAM_500 500
32 #define PARAM_1000 1000
33 #define PARAM_UNNORMAL (-1)
34 #define ETIMEDOUTS 110
35 
36 struct cndTimedWaitTime64Param {
37     cnd_t cnd;
38     mtx_t mutex;
39     unsigned sleep;
40 };
41 
CndTimedWaitTime64Thread(void * arg)42 static int CndTimedWaitTime64Thread(void *arg)
43 {
44     struct cndTimedWaitTime64Param *pparam = (cndTimedWaitTime64Param *)arg;
45 
46     mtx_lock(&(pparam->mutex));
47     if (pparam->sleep > PARAM_0) {
48         sleep(pparam->sleep);
49     }
50     cnd_signal(&(pparam->cnd));
51     mtx_unlock(&(pparam->mutex));
52 
53     thrd_exit(thrd_success);
54 }
55 
56 extern "C" int __cnd_timedwait_time64(cnd_t *__restrict, mtx_t *__restrict, const struct timespec *__restrict);
Cnd_timedWait_time64_One(napi_env env,napi_callback_info info)57 static napi_value Cnd_timedWait_time64_One(napi_env env, napi_callback_info info)
58 {
59     int ret = TEST_RESULT_FAILED;
60     thrd_t id;
61     struct cndTimedWaitTime64Param param;
62     struct timespec ts {};
63 
64     ret = cnd_init(&(param.cnd));
65     mtx_init(&(param.mutex), mtx_plain);
66     mtx_lock(&(param.mutex));
67     param.sleep = PARAM_0;
68     clock_gettime(CLOCK_REALTIME, &ts);
69     ts.tv_sec += PARAM_1;
70 
71     thrd_create(&id, CndTimedWaitTime64Thread, &param);
72     ret = __cnd_timedwait_time64(&(param.cnd), &(param.mutex), &ts);
73     thrd_join(id, nullptr);
74 
75     mtx_unlock(&(param.mutex));
76     mtx_destroy(&(param.mutex));
77     cnd_destroy(&(param.cnd));
78 
79     napi_value result = nullptr;
80     napi_create_int32(env, ret, &result);
81     return result;
82 }
83 
Cnd_timedWait_time64_Two(napi_env env,napi_callback_info info)84 static napi_value Cnd_timedWait_time64_Two(napi_env env, napi_callback_info info)
85 {
86     int ret = TEST_RESULT_FAILED;
87     thrd_t id;
88     struct cndTimedWaitTime64Param param;
89     struct timespec ts {};
90 
91     ret = cnd_init(&(param.cnd));
92     mtx_init(&(param.mutex), mtx_plain);
93     mtx_lock(&(param.mutex));
94     param.sleep = PARAM_2;
95     clock_gettime(CLOCK_REALTIME, &ts);
96     ts.tv_sec += PARAM_1;
97 
98     thrd_create(&id, CndTimedWaitTime64Thread, &param);
99     ret = __cnd_timedwait_time64(&(param.cnd), &(param.mutex), &ts);
100     thrd_join(id, nullptr);
101 
102     mtx_unlock(&(param.mutex));
103     mtx_destroy(&(param.mutex));
104     cnd_destroy(&(param.cnd));
105 
106     napi_value result = nullptr;
107     napi_create_int32(env, ret, &result);
108     return result;
109 }
110 
111 extern "C" pid_t __wait4_time64(pid_t, int *, int, struct rusage *);
Wait4_time64_One(napi_env env,napi_callback_info info)112 static napi_value Wait4_time64_One(napi_env env, napi_callback_info info)
113 {
114     int ret = TEST_RESULT_FAILED;
115     pid_t pid = fork();
116     if (pid > PARAM_0) {
117         int status = PARAM_0;
118         int options = PARAM_0;
119         struct rusage ru;
120         pid_t wait4ForPid = __wait4_time64(pid, &status, options, &ru);
121         if (wait4ForPid == pid && status == PARAM_0) {
122             ret = TEST_RESULT_PASSED;
123         }
124     } else {
125         sleep(PARAM_1);
126         exit(PARAM_0);
127     }
128 
129     napi_value result = nullptr;
130     napi_create_int32(env, ret, &result);
131     return result;
132 }
133 
Wait4_time64_Two(napi_env env,napi_callback_info info)134 static napi_value Wait4_time64_Two(napi_env env, napi_callback_info info)
135 {
136     int ret = TEST_RESULT_FAILED;
137     pid_t pid = fork();
138     if (pid > PARAM_0) {
139         int status = PARAM_0;
140         int options = PARAM_0;
141         struct rusage ru;
142         sleep(PARAM_1);
143         pid_t wait4ForPid = __wait4_time64(pid, &status, options, &ru);
144         if (wait4ForPid == pid && status == PARAM_0) {
145             ret = TEST_RESULT_PASSED;
146         }
147     } else {
148         sleep(PARAM_0);
149         exit(PARAM_0);
150     }
151 
152     napi_value result = nullptr;
153     napi_create_int32(env, ret, &result);
154     return result;
155 }
156 
157 #define NSEC_PER_SEC 1000000000
158 #define NSEC_PER_MSEC 1000000
159 #define MS_PER_S 1000
160 #define SLEEP_10_MS 10
161 #define SLEEP_100_MS 100
162 struct pthreadCondTimedwaitTime64Param {
163     pthread_cond_t cond;
164     pthread_mutex_t mutex;
165 };
166 extern "C" int __pthread_cond_timedwait_time64(pthread_cond_t *__restrict, pthread_mutex_t *__restrict,
167                                                const struct timespec *__restrict);
PThreadCondTimedWaitTime64Thread(void * arg)168 static void *PThreadCondTimedWaitTime64Thread(void *arg)
169 {
170     struct pthreadCondTimedwaitTime64Param *pparam = (pthreadCondTimedwaitTime64Param *)arg;
171     struct timespec ts {};
172     pthread_mutex_lock(&(pparam->mutex));
173     clock_gettime(CLOCK_REALTIME, &ts);
174     ts.tv_nsec += SLEEP_100_MS * NSEC_PER_MSEC;
175     if (ts.tv_nsec >= NSEC_PER_SEC) {
176         ts.tv_nsec -= NSEC_PER_SEC;
177         ts.tv_sec += PARAM_1;
178     }
179     int ret = __pthread_cond_timedwait_time64(&(pparam->cond), &(pparam->mutex), &ts);
180     pthread_mutex_unlock(&(pparam->mutex));
181     return (void *)ret;
182 }
183 
PThread_cond_timedWait_time64_One(napi_env env,napi_callback_info info)184 static napi_value PThread_cond_timedWait_time64_One(napi_env env, napi_callback_info info)
185 {
186     struct pthreadCondTimedwaitTime64Param param;
187     pthread_t threadId;
188     struct timespec ts {
189         PARAM_0, SLEEP_10_MS *NSEC_PER_MSEC
190     };
191     int ret = TEST_RESULT_FAILED;
192     param.cond = PTHREAD_COND_INITIALIZER;
193     param.mutex = PTHREAD_MUTEX_INITIALIZER;
194     pthread_create(&threadId, nullptr, PThreadCondTimedWaitTime64Thread, &param);
195     nanosleep(&ts, nullptr);
196     pthread_mutex_lock(&param.mutex);
197     pthread_cond_signal(&param.cond);
198     pthread_mutex_unlock(&param.mutex);
199     pthread_join(threadId, (void **)&ret);
200     pthread_cond_destroy(&param.cond);
201     pthread_mutex_destroy(&param.mutex);
202     napi_value result = nullptr;
203     napi_create_int32(env, ret, &result);
204     return result;
205 }
206 
PThread_cond_timedWait_time64_Two(napi_env env,napi_callback_info info)207 static napi_value PThread_cond_timedWait_time64_Two(napi_env env, napi_callback_info info)
208 {
209     struct pthreadCondTimedwaitTime64Param param;
210     pthread_t threadId;
211     int ret = TEST_RESULT_FAILED;
212     param.cond = PTHREAD_COND_INITIALIZER;
213     param.mutex = PTHREAD_MUTEX_INITIALIZER;
214     pthread_create(&threadId, nullptr, PThreadCondTimedWaitTime64Thread, &param);
215     pthread_join(threadId, (void **)&ret);
216     pthread_cond_destroy(&param.cond);
217     pthread_mutex_destroy(&param.mutex);
218     napi_value result = nullptr;
219     napi_create_int32(env, ret != ETIMEDOUTS, &result);
220     return result;
221 }
222 
223 extern "C" int __sem_timedwait_time64(sem_t *__restrict, const struct timespec *__restrict);
SemTimedWaitTime64Thread(void * arg)224 static void *SemTimedWaitTime64Thread(void *arg)
225 {
226     sem_t *psem = (sem_t *)arg;
227     struct timespec ts;
228     clock_gettime(CLOCK_REALTIME, &ts);
229     ts.tv_sec += PARAM_1;
230     int ret = __sem_timedwait_time64(psem, &ts);
231     return (void *)ret;
232 }
233 
Sem_timedWait_time64(napi_env env,napi_callback_info info)234 static napi_value Sem_timedWait_time64(napi_env env, napi_callback_info info)
235 {
236     int ret = PARAM_UNNORMAL;
237     pthread_t threadId;
238     sem_t sem;
239     sem_init(&sem, PARAM_0, PARAM_0);
240     pthread_create(&threadId, nullptr, SemTimedWaitTime64Thread, &sem);
241     usleep(PARAM_500 * PARAM_1000);
242     sem_post(&sem);
243     pthread_join(threadId, (void **)&ret);
244     sem_destroy(&sem);
245     napi_value result = nullptr;
246     napi_create_int32(env, ret, &result);
247     return result;
248 }
249 
250 EXTERN_C_START
Init(napi_env env,napi_value exports)251 static napi_value Init(napi_env env, napi_value exports)
252 {
253     napi_property_descriptor desc[] = {
254         {"__cnd_timedwait_time64_One", nullptr, Cnd_timedWait_time64_One, nullptr, nullptr, nullptr, napi_default,
255          nullptr},
256         {"__cnd_timedwait_time64_Two", nullptr, Cnd_timedWait_time64_Two, nullptr, nullptr, nullptr, napi_default,
257          nullptr},
258         {"__wait4_time64_One", nullptr, Wait4_time64_One, nullptr, nullptr, nullptr, napi_default, nullptr},
259         {"__wait4_time64_Two", nullptr, Wait4_time64_Two, nullptr, nullptr, nullptr, napi_default, nullptr},
260         {"__pthread_cond_timedwait_time64_One", nullptr, PThread_cond_timedWait_time64_One, nullptr, nullptr, nullptr,
261          napi_default, nullptr},
262         {"__pthread_cond_timedwait_time64_Two", nullptr, PThread_cond_timedWait_time64_Two, nullptr, nullptr, nullptr,
263          napi_default, nullptr},
264         {"__sem_timedwait_time64", nullptr, Sem_timedWait_time64, nullptr, nullptr, nullptr, napi_default, nullptr},
265     };
266     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
267     return exports;
268 }
269 EXTERN_C_END
270 
271 static napi_module demoModule = {
272     .nm_version = 1,
273     .nm_flags = 0,
274     .nm_filename = nullptr,
275     .nm_register_func = Init,
276     .nm_modname = "libfnmatchndk1",
277     .nm_priv = ((void *)0),
278     .reserved = {0},
279 };
280 
RegisterModule(void)281 extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&demoModule); }
282