1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2021-04-27     flybreak     the first version.
9  */
10 
11 #include <arm-tpl.h>
12 #include "tpl.h"
13 #include <cstdio>
14 #include <pthread.h>
15 
16 #define CPP11_DEFAULT_ID_OFFSET 1
17 
__ARM_TPL_thread_create(__ARM_TPL_thread_t * __t,void * (* __func)(void *),void * __arg)18 extern "C" int __ARM_TPL_thread_create(__ARM_TPL_thread_t *__t,
19                                        void *(*__func)(void *),
20                                        void *__arg)
21 {
22     int ret = 0;
23     pthread_t pid;
24     ret = pthread_create(&pid, RT_NULL, __func, __arg);
25     if (ret == 0)
26     {
27         __t->data = (std::uintptr_t)pid + CPP11_DEFAULT_ID_OFFSET;
28         return 0;
29     }
30     return -1;
31 }
32 
__ARM_TPL_thread_id_compare(__ARM_TPL_thread_id __tid1,__ARM_TPL_thread_id __tid2)33 extern "C" int __ARM_TPL_thread_id_compare(__ARM_TPL_thread_id __tid1,
34         __ARM_TPL_thread_id __tid2)
35 {
36     if (__tid1 > __tid2)
37         return 1;
38     else if (__tid1 < __tid2)
39         return -1;
40     else
41         return 0;
42 }
43 
__ARM_TPL_thread_get_current_id()44 extern "C" __ARM_TPL_thread_id __ARM_TPL_thread_get_current_id()
45 {
46     return (__ARM_TPL_thread_id)pthread_self();
47 }
48 
__ARM_TPL_thread_get_id(const __ARM_TPL_thread_t * __t)49 extern "C" __ARM_TPL_thread_id __ARM_TPL_thread_get_id(
50     const __ARM_TPL_thread_t *__t)
51 {
52     return (__ARM_TPL_thread_id)(((pthread_t)__t->data - CPP11_DEFAULT_ID_OFFSET));
53 }
54 
__ARM_TPL_thread_join(__ARM_TPL_thread_t * __t)55 extern "C" int __ARM_TPL_thread_join(__ARM_TPL_thread_t *__t)
56 {
57     pthread_join(((pthread_t)__t->data - CPP11_DEFAULT_ID_OFFSET), RT_NULL);
58     return 0;
59 }
60 
__ARM_TPL_thread_detach(__ARM_TPL_thread_t * __t)61 extern "C" int __ARM_TPL_thread_detach(__ARM_TPL_thread_t *__t)
62 {
63     pthread_detach(((pthread_t)__t->data - CPP11_DEFAULT_ID_OFFSET));
64     return 0;
65 }
66 
__ARM_TPL_thread_yield()67 extern "C" void __ARM_TPL_thread_yield()
68 {
69     rt_thread_yield();
70 }
71 
__ARM_TPL_thread_nanosleep(const __ARM_TPL_timespec_t * __req,__ARM_TPL_timespec_t * __rem)72 extern "C" int __ARM_TPL_thread_nanosleep(const __ARM_TPL_timespec_t *__req,
73         __ARM_TPL_timespec_t *__rem)
74 {
75     rt_tick_t tick;
76 
77     tick = __req->tv_sec * RT_TICK_PER_SECOND + (__req->tv_nsec * RT_TICK_PER_SECOND)/ 1000000000;
78     rt_thread_delay(tick);
79 
80     if (__rem)
81     {
82         tick = rt_tick_get() - tick;
83         /* get the passed time */
84         __rem->tv_sec = tick/RT_TICK_PER_SECOND;
85         __rem->tv_nsec = (tick%RT_TICK_PER_SECOND) * (1000000000/RT_TICK_PER_SECOND);
86     }
87     return 0;
88 }
89 
__ARM_TPL_thread_hw_concurrency()90 extern "C" unsigned __ARM_TPL_thread_hw_concurrency()
91 {
92     return 1;
93 }
94 
__ARM_TPL_tls_create(__ARM_TPL_tls_key * __key,void (* __at_exit)(void *))95 extern "C" int __ARM_TPL_tls_create(__ARM_TPL_tls_key *__key,
96                                     void (*__at_exit)(void *))
97 {
98     pthread_key_t key;
99 
100     if (pthread_key_create(&key, __at_exit) == 0)
101     {
102         *__key = key;
103         return 0;
104     }
105     return -1;
106 }
107 
__ARM_TPL_tls_get(__ARM_TPL_tls_key __key)108 extern "C" void *__ARM_TPL_tls_get(__ARM_TPL_tls_key __key)
109 {
110     return pthread_getspecific(__key);
111 }
112 
__ARM_TPL_tls_set(__ARM_TPL_tls_key __key,void * __p)113 extern "C" int __ARM_TPL_tls_set(__ARM_TPL_tls_key __key, void *__p)
114 {
115     if (pthread_setspecific(__key, (void*)__p) != 0)
116     {
117         return -1;
118     }
119     return 0;
120 }
121