• 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 <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(&param.cond);
94     mtx_init(&param.mutex, mtx_plain);
95     param.waitingThreads = PARAM_0;
96 
97     for (int i = PARAM_0; i < maxThreadNum; i++) {
98         thrd_create(&threadIds[i], CndBroadcastThread, &param);
99     }
100     mtx_lock(&param.mutex);
101     mtx_unlock(&param.mutex);
102     timespec ts = {.tv_nsec = 100 * 1000 * 1000};
103     thrd_sleep(&ts, nullptr);
104     mtx_lock(&param.mutex);
105     mtx_unlock(&param.mutex);
106     int ret = cnd_broadcast(&param.cond);
107     mtx_unlock(&param.mutex);
108 
109     for (int i = PARAM_0; i < maxThreadNum; i++) {
110         thrd_join(threadIds[i], nullptr);
111     }
112     mtx_destroy(&param.mutex);
113     cnd_destroy(&param.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(&param.cond);
161     mtx_init(&param.mutex, mtx_plain);
162     clock_gettime(CLOCK_REALTIME, &param.ts);
163     param.ts.tv_sec += PARAM_2;
164     param.waitRet = MPARAM_1;
165 
166     thrd_create(&threadId, CndSignalThread, &param);
167     sleep(PARAM_1);
168     mtx_lock(&param.mutex);
169     int ret = cnd_signal(&param.cond);
170     mtx_unlock(&param.mutex);
171 
172     thrd_join(threadId, nullptr);
173     ret |= param.waitRet;
174     mtx_destroy(&param.mutex);
175     cnd_destroy(&param.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(&param.cond);
186     mtx_init(&param.mutex, mtx_plain);
187     clock_gettime(CLOCK_REALTIME, &param.ts);
188     param.waitRet = MPARAM_1;
189 
190     thrd_create(&threadId, CndSignalThread, &param);
191     sleep(PARAM_1);
192     mtx_lock(&param.mutex);
193     int ret = cnd_signal(&param.cond);
194     mtx_unlock(&param.mutex);
195 
196     thrd_join(threadId, nullptr);
197     ret |= !param.waitRet;
198     mtx_destroy(&param.mutex);
199     cnd_destroy(&param.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, &param);
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, &param);
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, &param);
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