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 <csignal>
18 #include <threads.h>
19 #include <unistd.h>
20
21 #define PARAM_0 0
22 #define PARAM_3 3
23 #define PARAM_2 2
24 #define PARAM_1 1
25 #define MPARAM_1 (-1)
26 #define PARAM_10 10
27 #define PARAM_1000 1000
28 #define PARAM_100 100
29 #define FPARAM_100 100.0
30
31 struct callOnceParam {
32 mtx_t mutex;
33 int count;
34 once_flag flag;
35 };
36 static callOnceParam gCallOnce;
37
DoOnce(void)38 void DoOnce(void)
39 {
40 mtx_lock(&gCallOnce.mutex);
41 gCallOnce.count++;
42 mtx_unlock(&gCallOnce.mutex);
43 }
44
OnceFunc(void * data)45 static void OnceFunc(void *data) { call_once(&gCallOnce.flag, DoOnce); }
46
CallOnce(napi_env env,napi_callback_info info)47 static napi_value CallOnce(napi_env env, napi_callback_info info)
48 {
49 napi_value result = nullptr;
50 mtx_init(&gCallOnce.mutex, mtx_plain);
51 gCallOnce.count = PARAM_0;
52 gCallOnce.flag = ONCE_FLAG_INIT;
53 thrd_t thread1;
54 thrd_t thread2;
55 thrd_t thread3;
56 thrd_t thread4;
57 thrd_create(&thread1, (thrd_start_t)OnceFunc, nullptr);
58 thrd_create(&thread2, (thrd_start_t)OnceFunc, nullptr);
59 thrd_create(&thread3, (thrd_start_t)OnceFunc, nullptr);
60 thrd_create(&thread4, (thrd_start_t)OnceFunc, nullptr);
61 thrd_join(thread1, nullptr);
62 thrd_join(thread2, nullptr);
63 thrd_join(thread3, nullptr);
64 thrd_join(thread4, nullptr);
65 int ret = gCallOnce.count;
66 mtx_destroy(&gCallOnce.mutex);
67 napi_create_int32(env, ret, &result);
68 return result;
69 }
70
71 struct cndBroadcastParam {
72 mtx_t mutex;
73 cnd_t cond;
74 unsigned int waitingThreads;
75 };
CndBroadcastThread(void * data)76 static int CndBroadcastThread(void *data)
77 {
78 cndBroadcastParam *pparam = (cndBroadcastParam *)data;
79 mtx_lock(&pparam->mutex);
80 pparam->waitingThreads++;
81 cnd_wait(&pparam->cond, &pparam->mutex);
82 pparam->waitingThreads--;
83 mtx_unlock(&pparam->mutex);
84 thrd_exit(thrd_success);
85 }
86
Cnd_broadcast(napi_env env,napi_callback_info info)87 static napi_value Cnd_broadcast(napi_env env, napi_callback_info info)
88 {
89 napi_value result = nullptr;
90 const int maxThreadNum = PARAM_3;
91 thrd_t threadIds[maxThreadNum];
92 cndBroadcastParam param;
93 cnd_init(¶m.cond);
94 mtx_init(¶m.mutex, mtx_plain);
95 param.waitingThreads = PARAM_0;
96
97 for (int i = PARAM_0; i < maxThreadNum; i++) {
98 thrd_create(&threadIds[i], CndBroadcastThread, ¶m);
99 }
100 mtx_lock(¶m.mutex);
101 mtx_unlock(¶m.mutex);
102 timespec ts = {.tv_nsec = 100 * 1000 * 1000};
103 thrd_sleep(&ts, nullptr);
104 mtx_lock(¶m.mutex);
105 mtx_unlock(¶m.mutex);
106 int ret = cnd_broadcast(¶m.cond);
107 mtx_unlock(¶m.mutex);
108
109 for (int i = PARAM_0; i < maxThreadNum; i++) {
110 thrd_join(threadIds[i], nullptr);
111 }
112 mtx_destroy(¶m.mutex);
113 cnd_destroy(¶m.cond);
114 ret += param.waitingThreads;
115 napi_create_int32(env, ret, &result);
116 return result;
117 }
118
Cnd_destroy(napi_env env,napi_callback_info info)119 static napi_value Cnd_destroy(napi_env env, napi_callback_info info)
120 {
121 cnd_t cond;
122 int ret = cnd_init(&cond);
123 cnd_destroy(&cond);
124 ret = cnd_init(&cond);
125 cnd_destroy(&cond);
126 napi_value result = nullptr;
127 napi_create_int32(env, ret, &result);
128 return result;
129 }
130
Cnd_init(napi_env env,napi_callback_info info)131 static napi_value Cnd_init(napi_env env, napi_callback_info info)
132 {
133 cnd_t cond;
134 int ret = cnd_init(&cond);
135 cnd_destroy(&cond);
136 napi_value result = nullptr;
137 napi_create_int32(env, ret, &result);
138 return result;
139 }
140
141 struct cndSignalParam {
142 mtx_t mutex;
143 cnd_t cond;
144 timespec ts;
145 int waitRet;
146 };
CndSignalThread(void * data)147 static int CndSignalThread(void *data)
148 {
149 cndSignalParam *pparam = (cndSignalParam *)data;
150 mtx_lock(&pparam->mutex);
151 pparam->waitRet = cnd_timedwait(&pparam->cond, &pparam->mutex, &pparam->ts);
152 mtx_unlock(&pparam->mutex);
153 thrd_exit(thrd_success);
154 }
Cnd_signal_One(napi_env env,napi_callback_info info)155 static napi_value Cnd_signal_One(napi_env env, napi_callback_info info)
156 {
157 napi_value result = nullptr;
158 thrd_t threadId;
159 cndSignalParam param;
160 cnd_init(¶m.cond);
161 mtx_init(¶m.mutex, mtx_plain);
162 clock_gettime(CLOCK_REALTIME, ¶m.ts);
163 param.ts.tv_sec += PARAM_2;
164 param.waitRet = MPARAM_1;
165
166 thrd_create(&threadId, CndSignalThread, ¶m);
167 sleep(PARAM_1);
168 mtx_lock(¶m.mutex);
169 int ret = cnd_signal(¶m.cond);
170 mtx_unlock(¶m.mutex);
171
172 thrd_join(threadId, nullptr);
173 ret |= param.waitRet;
174 mtx_destroy(¶m.mutex);
175 cnd_destroy(¶m.cond);
176 napi_create_int32(env, ret, &result);
177 return result;
178 }
179
Cnd_signal_Two(napi_env env,napi_callback_info info)180 static napi_value Cnd_signal_Two(napi_env env, napi_callback_info info)
181 {
182 napi_value result = nullptr;
183 thrd_t threadId;
184 cndSignalParam param;
185 cnd_init(¶m.cond);
186 mtx_init(¶m.mutex, mtx_plain);
187 clock_gettime(CLOCK_REALTIME, ¶m.ts);
188 param.waitRet = MPARAM_1;
189
190 thrd_create(&threadId, CndSignalThread, ¶m);
191 sleep(PARAM_1);
192 mtx_lock(¶m.mutex);
193 int ret = cnd_signal(¶m.cond);
194 mtx_unlock(¶m.mutex);
195
196 thrd_join(threadId, nullptr);
197 ret |= !param.waitRet;
198 mtx_destroy(¶m.mutex);
199 cnd_destroy(¶m.cond);
200 napi_create_int32(env, ret, &result);
201 return result;
202 }
203
MtxDestroy(napi_env env,napi_callback_info info)204 static napi_value MtxDestroy(napi_env env, napi_callback_info info)
205 {
206 mtx_t mutex;
207 int ret = mtx_init(&mutex, mtx_plain);
208 mtx_destroy(&mutex);
209 ret = mtx_init(&mutex, mtx_plain);
210 mtx_destroy(&mutex);
211 napi_value result = nullptr;
212 napi_create_int32(env, ret, &result);
213 return result;
214 }
215
MtxInit_One(napi_env env,napi_callback_info info)216 static napi_value MtxInit_One(napi_env env, napi_callback_info info)
217 {
218 mtx_t mutex;
219 int ret = mtx_init(&mutex, mtx_plain);
220 mtx_destroy(&mutex);
221 napi_value result = nullptr;
222 napi_create_int32(env, ret, &result);
223 return result;
224 }
225
MtxInit_Two(napi_env env,napi_callback_info info)226 static napi_value MtxInit_Two(napi_env env, napi_callback_info info)
227 {
228 mtx_t mutex;
229 int ret = mtx_init(&mutex, mtx_timed);
230 mtx_destroy(&mutex);
231 napi_value result = nullptr;
232 napi_create_int32(env, ret, &result);
233 return result;
234 }
235
MtxInit_Three(napi_env env,napi_callback_info info)236 static napi_value MtxInit_Three(napi_env env, napi_callback_info info)
237 {
238 mtx_t mutex;
239 int ret = mtx_init(&mutex, mtx_plain | mtx_recursive);
240 mtx_destroy(&mutex);
241 napi_value result = nullptr;
242 napi_create_int32(env, ret, &result);
243 return result;
244 }
245
MtxInit_Four(napi_env env,napi_callback_info info)246 static napi_value MtxInit_Four(napi_env env, napi_callback_info info)
247 {
248 mtx_t mutex;
249 int ret = mtx_init(&mutex, mtx_timed | mtx_recursive);
250 mtx_destroy(&mutex);
251 napi_value result = nullptr;
252 napi_create_int32(env, ret, &result);
253 return result;
254 }
255
MtxLockThread(void * data)256 static int MtxLockThread(void *data)
257 {
258 mtx_t *pmutex = (mtx_t *)data;
259 int ret = mtx_lock(pmutex);
260 mtx_unlock(pmutex);
261 thrd_exit(ret);
262 }
263
MtxRecursiveLock(void * data)264 static int MtxRecursiveLock(void *data)
265 {
266 mtx_t *pmutex = (mtx_t *)data;
267 int ret = mtx_lock(pmutex);
268 ret |= mtx_lock(pmutex);
269 mtx_unlock(pmutex);
270 thrd_exit(ret);
271 }
272
MtxLock_One(napi_env env,napi_callback_info info)273 static napi_value MtxLock_One(napi_env env, napi_callback_info info)
274 {
275 mtx_t mutex;
276 thrd_t threadId;
277 int ret;
278 mtx_init(&mutex, mtx_plain);
279 thrd_create(&threadId, MtxLockThread, &mutex);
280 thrd_join(threadId, &ret);
281 mtx_destroy(&mutex);
282 napi_value result = nullptr;
283 napi_create_int32(env, ret, &result);
284 return result;
285 }
286
MtxLock_Two(napi_env env,napi_callback_info info)287 static napi_value MtxLock_Two(napi_env env, napi_callback_info info)
288 {
289 mtx_t mutex;
290 thrd_t threadId;
291 int ret;
292 mtx_init(&mutex, mtx_timed);
293 thrd_create(&threadId, MtxLockThread, &mutex);
294 thrd_join(threadId, &ret);
295 mtx_destroy(&mutex);
296 napi_value result = nullptr;
297 napi_create_int32(env, ret, &result);
298 return result;
299 }
300
MtxLock_Three(napi_env env,napi_callback_info info)301 static napi_value MtxLock_Three(napi_env env, napi_callback_info info)
302 {
303 mtx_t mutex;
304 thrd_t threadId;
305 int ret;
306 mtx_init(&mutex, mtx_plain | mtx_recursive);
307 thrd_create(&threadId, MtxRecursiveLock, &mutex);
308 thrd_join(threadId, &ret);
309 mtx_destroy(&mutex);
310 napi_value result = nullptr;
311 napi_create_int32(env, ret, &result);
312 return result;
313 }
314
MtxLock_Four(napi_env env,napi_callback_info info)315 static napi_value MtxLock_Four(napi_env env, napi_callback_info info)
316 {
317 mtx_t mutex;
318 thrd_t threadId;
319 int ret;
320 mtx_init(&mutex, mtx_timed | mtx_recursive);
321 thrd_create(&threadId, MtxRecursiveLock, &mutex);
322 thrd_join(threadId, &ret);
323 mtx_destroy(&mutex);
324 napi_value result = nullptr;
325 napi_create_int32(env, ret, &result);
326 return result;
327 }
328
MtxTimedLock_One(napi_env env,napi_callback_info info)329 static napi_value MtxTimedLock_One(napi_env env, napi_callback_info info)
330 {
331 mtx_t mutex;
332 timespec ts = {2, 0};
333 mtx_init(&mutex, mtx_timed);
334 int ret = mtx_timedlock(&mutex, &ts);
335 mtx_unlock(&mutex);
336 mtx_destroy(&mutex);
337 napi_value result = nullptr;
338 napi_create_int32(env, ret, &result);
339 return result;
340 }
341
MtxTimedLock_Two(napi_env env,napi_callback_info info)342 static napi_value MtxTimedLock_Two(napi_env env, napi_callback_info info)
343 {
344 mtx_t mutex;
345 timespec ts = {2, 0};
346 mtx_init(&mutex, mtx_timed);
347 mtx_lock(&mutex);
348 int ret = mtx_timedlock(&mutex, &ts);
349 mtx_unlock(&mutex);
350 mtx_destroy(&mutex);
351 napi_value result = nullptr;
352 napi_create_int32(env, ret, &result);
353 return result;
354 }
355
MtxTryLockThread(void * data)356 static int MtxTryLockThread(void *data)
357 {
358 mtx_t *pmutex = (mtx_t *)data;
359 int ret = mtx_lock(pmutex);
360 ret = mtx_trylock(pmutex);
361 mtx_unlock(pmutex);
362 thrd_exit(ret);
363 }
364
MtxTryLock_One(napi_env env,napi_callback_info info)365 static napi_value MtxTryLock_One(napi_env env, napi_callback_info info)
366 {
367 mtx_t mutex;
368 thrd_t threadId;
369 int ret;
370 mtx_init(&mutex, mtx_plain | mtx_recursive);
371 thrd_create(&threadId, MtxTryLockThread, &mutex);
372 thrd_join(threadId, &ret);
373 mtx_destroy(&mutex);
374 napi_value result = nullptr;
375 napi_create_int32(env, ret, &result);
376 return result;
377 }
378
MtxTryLock_Two(napi_env env,napi_callback_info info)379 static napi_value MtxTryLock_Two(napi_env env, napi_callback_info info)
380 {
381 mtx_t mutex;
382 thrd_t threadId;
383 int ret;
384 mtx_init(&mutex, mtx_plain);
385 thrd_create(&threadId, MtxTryLockThread, &mutex);
386 thrd_join(threadId, &ret);
387 mtx_destroy(&mutex);
388 napi_value result = nullptr;
389 napi_create_int32(env, ret, &result);
390 return result;
391 }
392
MtxUnlock_One(napi_env env,napi_callback_info info)393 static napi_value MtxUnlock_One(napi_env env, napi_callback_info info)
394 {
395 mtx_t mutex;
396 mtx_init(&mutex, mtx_plain);
397 int ret = mtx_lock(&mutex);
398 ret = mtx_unlock(&mutex);
399 mtx_destroy(&mutex);
400 napi_value result = nullptr;
401 napi_create_int32(env, ret, &result);
402 return result;
403 }
404
MtxUnlock_Two(napi_env env,napi_callback_info info)405 static napi_value MtxUnlock_Two(napi_env env, napi_callback_info info)
406 {
407 mtx_t mutex;
408 mtx_init(&mutex, mtx_plain);
409 int ret = mtx_lock(&mutex);
410 ret = mtx_unlock(&mutex);
411 ret = mtx_unlock(&mutex);
412 mtx_destroy(&mutex);
413 napi_value result = nullptr;
414 napi_create_int32(env, ret, &result);
415 return result;
416 }
417
ThrdCreateThread(void * arg)418 static int ThrdCreateThread(void *arg)
419 {
420 int ret = *(static_cast<int*>(arg));
421 thrd_exit(ret);
422 }
423
Thrd_create(napi_env env,napi_callback_info info)424 static napi_value Thrd_create(napi_env env, napi_callback_info info)
425 {
426 int threadArg = PARAM_1;
427 int threadRet = PARAM_0;
428 thrd_t threadId;
429 int ret = thrd_create(&threadId, ThrdCreateThread, &threadArg);
430 thrd_join(threadId, &threadRet);
431 ret |= threadArg != threadRet;
432 napi_value result = nullptr;
433 napi_create_int32(env, ret, &result);
434 return result;
435 }
436
437 struct thrdCurrentParam {
438 thrd_t threadId;
439 };
440
ThrdCurrentThread(void * arg)441 static int ThrdCurrentThread(void *arg)
442 {
443 thrdCurrentParam *pparam = (thrdCurrentParam *)arg;
444 pparam->threadId = thrd_current();
445 thrd_exit(thrd_success);
446 }
447
Thrd_current(napi_env env,napi_callback_info info)448 static napi_value Thrd_current(napi_env env, napi_callback_info info)
449 {
450 thrdCurrentParam param;
451 thrd_t threadId;
452 thrd_create(&threadId, ThrdCurrentThread, ¶m);
453 thrd_join(threadId, nullptr);
454 int ret = thrd_equal(threadId, param.threadId);
455 napi_value result = nullptr;
456 napi_create_int32(env, ret, &result);
457 return result;
458 }
459
ThrdDetachThreadA(void * arg)460 static int ThrdDetachThreadA(void *arg)
461 {
462 int *pret = static_cast<int*>(arg);
463 *pret = thrd_detach(thrd_current());
464 thrd_exit(thrd_success);
465 }
466
ThrdDetachThreadB(void * arg)467 static int ThrdDetachThreadB(void *arg)
468 {
469 timespec ts = {1, 0};
470 thrd_sleep(&ts, nullptr);
471 thrd_exit(thrd_success);
472 }
473
Thrd_detach_One(napi_env env,napi_callback_info info)474 static napi_value Thrd_detach_One(napi_env env, napi_callback_info info)
475 {
476 thrd_t threadId;
477 int ret = MPARAM_1;
478 timespec ts = {1, 0};
479 thrd_create(&threadId, ThrdDetachThreadA, &ret);
480 thrd_sleep(&ts, nullptr);
481 napi_value result = nullptr;
482 napi_create_int32(env, ret, &result);
483 return result;
484 }
485
Thrd_detach_Two(napi_env env,napi_callback_info info)486 static napi_value Thrd_detach_Two(napi_env env, napi_callback_info info)
487 {
488 thrd_t threadId;
489 thrd_create(&threadId, ThrdDetachThreadB, nullptr);
490 int ret = thrd_detach(threadId);
491 napi_value result = nullptr;
492 napi_create_int32(env, ret, &result);
493 return result;
494 }
495
496 struct thrdEqualParam {
497 thrd_t threadId;
498 };
499
ThrdEqualThread(void * arg)500 static int ThrdEqualThread(void *arg)
501 {
502 thrdEqualParam *pparam = (thrdEqualParam *)arg;
503 pparam->threadId = thrd_current();
504 thrd_exit(thrd_success);
505 }
506
Thrd_equal_One(napi_env env,napi_callback_info info)507 static napi_value Thrd_equal_One(napi_env env, napi_callback_info info)
508 {
509 thrdEqualParam param;
510 thrd_t threadId;
511 thrd_create(&threadId, ThrdEqualThread, ¶m);
512 thrd_join(threadId, nullptr);
513 int ret = thrd_equal(threadId, param.threadId);
514 napi_value result = nullptr;
515 napi_create_int32(env, ret, &result);
516 return result;
517 }
518
Thrd_equal_Two(napi_env env,napi_callback_info info)519 static napi_value Thrd_equal_Two(napi_env env, napi_callback_info info)
520 {
521 thrdEqualParam param;
522 thrd_t threadId;
523 thrd_create(&threadId, ThrdEqualThread, ¶m);
524 thrd_t currentId = thrd_current();
525 int ret = thrd_equal(threadId, currentId);
526 thrd_join(threadId, nullptr);
527 napi_value result = nullptr;
528 napi_create_int32(env, ret, &result);
529 return result;
530 }
531
ThrdExitThread(void * arg)532 static int ThrdExitThread(void *arg)
533 {
534 int ret = *(static_cast<int*>(arg));
535 thrd_exit(ret);
536 }
537
Thrd_exit(napi_env env,napi_callback_info info)538 static napi_value Thrd_exit(napi_env env, napi_callback_info info)
539 {
540 int expectRet = PARAM_1;
541 int threadRet = PARAM_0;
542 thrd_t threadId;
543 thrd_create(&threadId, ThrdExitThread, &expectRet);
544 thrd_join(threadId, &threadRet);
545 int ret = expectRet == threadRet;
546 napi_value result = nullptr;
547 napi_create_int32(env, !ret, &result);
548 return result;
549 }
550
ThrdJoinThread(void * arg)551 static int ThrdJoinThread(void *arg)
552 {
553 int ret = *(static_cast<int*>(arg));
554 thrd_exit(ret);
555 }
556
Thrd_join_One(napi_env env,napi_callback_info info)557 static napi_value Thrd_join_One(napi_env env, napi_callback_info info)
558 {
559 int expectRet = PARAM_1;
560 int threadRet = PARAM_0;
561 thrd_t threadId;
562 thrd_create(&threadId, ThrdJoinThread, &expectRet);
563 int ret = thrd_join(threadId, &threadRet);
564 ret |= expectRet != threadRet;
565 napi_value result = nullptr;
566 napi_create_int32(env, ret, &result);
567 return result;
568 }
569
Thrd_join_Two(napi_env env,napi_callback_info info)570 static napi_value Thrd_join_Two(napi_env env, napi_callback_info info)
571 {
572 int expectRet = PARAM_1;
573 thrd_t threadId;
574 thrd_create(&threadId, ThrdJoinThread, &expectRet);
575 int ret = thrd_join(threadId, nullptr);
576 napi_value result = nullptr;
577 napi_create_int32(env, ret, &result);
578 return result;
579 }
580
581 #define ms (1000.0)
582 #define us (1000000)
583 #define ns (1000000000L)
ustimer(timespec tss,timespec tse)584 static double ustimer(timespec tss, timespec tse)
585 {
586 double sd = difftime(tse.tv_sec, tss.tv_sec);
587 long nsd = tse.tv_nsec - tss.tv_nsec;
588 if (nsd < PARAM_0) {
589 return us * (sd - PARAM_1) + (ns + nsd) / ms;
590 } else {
591 return us * (sd) + nsd / ms;
592 }
593 }
594
Thrd_sleep(napi_env env,napi_callback_info info)595 static napi_value Thrd_sleep(napi_env env, napi_callback_info info)
596 {
597 timespec ts = {0, 10 * us};
598 timespec start, end, remain;
599 timespec_get(&start, TIME_UTC);
600 int ret = thrd_sleep(&ts, &remain);
601 timespec_get(&end, TIME_UTC);
602 double elapsed = ustimer(start, end);
603 ret |= elapsed < PARAM_10 * ms;
604 napi_value result = nullptr;
605 napi_create_int32(env, ret, &result);
606 return result;
607 }
608
Thrd_yield(napi_env env,napi_callback_info info)609 static napi_value Thrd_yield(napi_env env, napi_callback_info info)
610 {
611 const double elapsedMax = FPARAM_100;
612 timespec start;
613 timespec end;
614 timespec_get(&start, TIME_UTC);
615 do {
616 thrd_yield();
617 timespec_get(&end, TIME_UTC);
618 } while (ustimer(start, end) < elapsedMax);
619 double elapsed = ustimer(start, end);
620 int ret = elapsed < elapsedMax;
621 napi_value result = nullptr;
622 napi_create_int32(env, ret, &result);
623 return result;
624 }
625
Tss_create(napi_env env,napi_callback_info info)626 static napi_value Tss_create(napi_env env, napi_callback_info info)
627 {
628 tss_t key;
629 int ret = tss_create(&key, nullptr);
630 tss_delete(key);
631 napi_value result = nullptr;
632 napi_create_int32(env, ret, &result);
633 return result;
634 }
635
Tss_delete(napi_env env,napi_callback_info info)636 static napi_value Tss_delete(napi_env env, napi_callback_info info)
637 {
638 tss_t key;
639 int ret = tss_create(&key, nullptr);
640 tss_delete(key);
641 ret |= tss_create(&key, nullptr);
642 tss_delete(key);
643 napi_value result = nullptr;
644 napi_create_int32(env, ret, &result);
645 return result;
646 }
647
Tss_get(napi_env env,napi_callback_info info)648 static napi_value Tss_get(napi_env env, napi_callback_info info)
649 {
650 tss_t key;
651 int setValue = PARAM_1;
652 tss_create(&key, nullptr);
653 int ret = tss_set(key, static_cast<void *>(&setValue));
654 int value =*static_cast<int*>(tss_get(key));
655 tss_delete(key);
656
657 ret |= value != setValue;
658 napi_value result = nullptr;
659 napi_create_int32(env, ret, &result);
660 return result;
661 }
662
Tss_set(napi_env env,napi_callback_info info)663 static napi_value Tss_set(napi_env env, napi_callback_info info)
664 {
665 tss_t key;
666 int setValue = PARAM_1;
667 tss_create(&key, nullptr);
668 int ret = tss_set(key, static_cast<void *>(&setValue));
669 int value =*static_cast<int*>(tss_get(key));
670 tss_delete(key);
671
672 ret |= value != setValue;
673 napi_value result = nullptr;
674 napi_create_int32(env, ret, &result);
675 return result;
676 }
677
678 EXTERN_C_START
Init(napi_env env,napi_value exports)679 static napi_value Init(napi_env env, napi_value exports)
680 {
681 napi_property_descriptor desc[] = {
682 {"callOnce", nullptr, CallOnce, nullptr, nullptr, nullptr, napi_default, nullptr},
683 {"cnd_broadcast", nullptr, Cnd_broadcast, nullptr, nullptr, nullptr, napi_default, nullptr},
684 {"cnd_destroy", nullptr, Cnd_destroy, nullptr, nullptr, nullptr, napi_default, nullptr},
685 {"cnd_init", nullptr, Cnd_init, nullptr, nullptr, nullptr, napi_default, nullptr},
686 {"cnd_signal_One", nullptr, Cnd_signal_One, nullptr, nullptr, nullptr, napi_default, nullptr},
687 {"cnd_signal_Two", nullptr, Cnd_signal_Two, nullptr, nullptr, nullptr, napi_default, nullptr},
688 {"mtxDestroy", nullptr, MtxDestroy, nullptr, nullptr, nullptr, napi_default, nullptr},
689 {"mtxInit_One", nullptr, MtxInit_One, nullptr, nullptr, nullptr, napi_default, nullptr},
690 {"mtxInit_Two", nullptr, MtxInit_Two, nullptr, nullptr, nullptr, napi_default, nullptr},
691 {"mtxInit_Three", nullptr, MtxInit_Three, nullptr, nullptr, nullptr, napi_default, nullptr},
692 {"mtxInit_Four", nullptr, MtxInit_Four, nullptr, nullptr, nullptr, napi_default, nullptr},
693 {"mtxLock_One", nullptr, MtxLock_One, nullptr, nullptr, nullptr, napi_default, nullptr},
694 {"mtxLock_Two", nullptr, MtxLock_Two, nullptr, nullptr, nullptr, napi_default, nullptr},
695 {"mtxLock_Three", nullptr, MtxLock_Three, nullptr, nullptr, nullptr, napi_default, nullptr},
696 {"mtxLock_Four", nullptr, MtxLock_Four, nullptr, nullptr, nullptr, napi_default, nullptr},
697 {"mtxTimedLock_One", nullptr, MtxTimedLock_One, nullptr, nullptr, nullptr, napi_default, nullptr},
698 {"mtxTimedLock_Two", nullptr, MtxTimedLock_Two, nullptr, nullptr, nullptr, napi_default, nullptr},
699 {"mtxTryLock_One", nullptr, MtxTryLock_One, nullptr, nullptr, nullptr, napi_default, nullptr},
700 {"mtxTryLock_Two", nullptr, MtxTryLock_Two, nullptr, nullptr, nullptr, napi_default, nullptr},
701 {"mtxUnlock_One", nullptr, MtxUnlock_One, nullptr, nullptr, nullptr, napi_default, nullptr},
702 {"mtxUnlock_Two", nullptr, MtxUnlock_Two, nullptr, nullptr, nullptr, napi_default, nullptr},
703 {"thrd_create", nullptr, Thrd_create, nullptr, nullptr, nullptr, napi_default, nullptr},
704 {"thrd_current", nullptr, Thrd_current, nullptr, nullptr, nullptr, napi_default, nullptr},
705 {"thrd_detach_One", nullptr, Thrd_detach_One, nullptr, nullptr, nullptr, napi_default, nullptr},
706 {"thrd_detach_Two", nullptr, Thrd_detach_Two, nullptr, nullptr, nullptr, napi_default, nullptr},
707 {"thrd_equal_One", nullptr, Thrd_equal_One, nullptr, nullptr, nullptr, napi_default, nullptr},
708 {"thrd_equal_Two", nullptr, Thrd_equal_Two, nullptr, nullptr, nullptr, napi_default, nullptr},
709 {"thrd_exit", nullptr, Thrd_exit, nullptr, nullptr, nullptr, napi_default, nullptr},
710 {"thrd_join_One", nullptr, Thrd_join_One, nullptr, nullptr, nullptr, napi_default, nullptr},
711 {"thrd_join_Two", nullptr, Thrd_join_Two, nullptr, nullptr, nullptr, napi_default, nullptr},
712 {"thrd_sleep", nullptr, Thrd_sleep, nullptr, nullptr, nullptr, napi_default, nullptr},
713 {"thrd_yield", nullptr, Thrd_yield, nullptr, nullptr, nullptr, napi_default, nullptr},
714 {"tss_create", nullptr, Tss_create, nullptr, nullptr, nullptr, napi_default, nullptr},
715 {"tss_delete", nullptr, Tss_delete, nullptr, nullptr, nullptr, napi_default, nullptr},
716 {"tss_get", nullptr, Tss_get, nullptr, nullptr, nullptr, napi_default, nullptr},
717 {"tss_set", nullptr, Tss_set, nullptr, nullptr, nullptr, napi_default, nullptr},
718 };
719 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
720 return exports;
721 }
722 EXTERN_C_END
723
724 static napi_module demoModule = {
725 .nm_version = 1,
726 .nm_flags = 0,
727 .nm_filename = nullptr,
728 .nm_register_func = Init,
729 .nm_modname = "threads",
730 .nm_priv = ((void *)0),
731 .reserved = {0},
732 };
733
RegisterModule(void)734 extern "C" __attribute__((constructor)) void RegisterModule(void) { napi_module_register(&demoModule); }
735