1+ #include < bits/gthr-default.h>
2+ #include < errno.h>
3+ #include < stdlib.h>
4+ #include < malloc.h>
5+
6+ #include " lwp.h"
7+ #include " mutex.h"
8+ #include " cond.h"
9+
10+ #define __OGC_GTHR_BASE_PRIO (64 )
11+
12+ #define __OGC_ONCE_INIT (0 )
13+ #define __OGC_ONCE_STARTED (1 )
14+ #define __OGC_ONCE_DONE (2 )
15+
16+ extern " C" {
17+
18+ typedef struct {
19+ lwpq_t queue;
20+ lwp_t thread;
21+ } gthr_thread_t ;
22+
23+ int __gthr_impl_active (void )
24+ {
25+ return 1 ;
26+ }
27+
28+ int __gthr_impl_create (__gthread_t *__threadid, void *(*__func) (void *), void *__args)
29+ {
30+ gthr_thread_t *th = (gthr_thread_t *)malloc (sizeof (gthr_thread_t ));
31+
32+ if (!th) {
33+ return ENOMEM;
34+ }
35+
36+ if (LWP_InitQueue (&th->queue ) != LWP_SUCCESSFUL) {
37+ free (th);
38+ return EINVAL;
39+ }
40+
41+ if (LWP_CreateThread (&th->thread , __func, __args, NULL , 0 , __OGC_GTHR_BASE_PRIO) != LWP_SUCCESSFUL) {
42+ LWP_CloseQueue (th->queue );
43+ free (th);
44+ return EINVAL;
45+ }
46+
47+ *__threadid = (__gthread_t )th;
48+ return 0 ;
49+ }
50+
51+ int __gthr_impl_join (__gthread_t __threadid, void **__value_ptr)
52+ {
53+ gthr_thread_t *th = (gthr_thread_t *)__threadid;
54+
55+ int res = LWP_JoinThread (th->thread , __value_ptr);
56+ if (res != LWP_SUCCESSFUL) {
57+ return -1 ;
58+ }
59+
60+ /* Clean up thread data */
61+ LWP_CloseQueue (th->queue );
62+ free (th);
63+
64+ return 0 ;
65+ }
66+
67+ int __gthr_impl_detach (__gthread_t __threadid)
68+ {
69+ /* Not supported */
70+ return -1 ;
71+ }
72+
73+ int __gthr_impl_equal (__gthread_t __t1, __gthread_t __t2)
74+ {
75+ return (gthr_thread_t *)__t1 == (gthr_thread_t *)__t2;
76+ }
77+
78+ __gthread_t __gthr_impl_self (void )
79+ {
80+ /*
81+ HACK: __gthread_self() is only used for std::thread::get_id(), so returning
82+ LWP_GetSelf() works as a unique id even though it's technically not a thread
83+ */
84+ return (__gthread_t )LWP_GetSelf ();
85+ }
86+
87+ int __gthr_impl_yield (void )
88+ {
89+ LWP_YieldThread ();
90+ return 0 ;
91+ }
92+
93+ int __gthr_impl_once (__gthread_once_t *__once, void (*__func) (void ))
94+ {
95+ uint32_t expected = __OGC_ONCE_INIT;
96+ if (__atomic_compare_exchange_n ((uint32_t *)__once, &expected,
97+ __OGC_ONCE_STARTED, false , __ATOMIC_ACQUIRE,
98+ __ATOMIC_RELAXED)) {
99+ __func ();
100+ __atomic_store_n ((uint32_t *)__once, __OGC_ONCE_DONE, __ATOMIC_RELEASE);
101+ } else if (expected != __OGC_ONCE_DONE) {
102+ do {
103+ __atomic_load ((uint32_t *)__once, &expected, __ATOMIC_ACQUIRE);
104+ } while (expected != __OGC_ONCE_DONE);
105+ }
106+
107+ return 0 ;
108+ }
109+
110+ void __gthr_impl_mutex_init_function (__gthread_mutex_t *mutex)
111+ {
112+ LWP_MutexInit (((mutex_t *)mutex), false );
113+ }
114+
115+ int __gthr_impl_mutex_lock (__gthread_mutex_t *mutex)
116+ {
117+ return LWP_MutexLock (*((mutex_t *)mutex));
118+ }
119+
120+ int __gthr_impl_mutex_trylock (__gthread_mutex_t *mutex)
121+ {
122+ return LWP_MutexTryLock (*((mutex_t *)mutex));
123+ }
124+
125+ int __gthr_impl_mutex_unlock (__gthread_mutex_t *mutex)
126+ {
127+ return LWP_MutexUnlock (*((mutex_t *)mutex));
128+ }
129+
130+ int __gthr_impl_mutex_destroy (__gthread_mutex_t *mutex)
131+ {
132+ return LWP_MutexDestroy (*((mutex_t *)mutex));
133+ }
134+
135+ int __gthr_impl_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
136+ {
137+ return LWP_MutexInit (((mutex_t *)mutex), true );
138+ }
139+
140+ int __gthr_impl_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
141+ {
142+ return LWP_MutexLock (*((mutex_t *)mutex));
143+ }
144+
145+ int __gthr_impl_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
146+ {
147+ return LWP_MutexTryLock (*((mutex_t *)mutex));
148+ }
149+
150+ int __gthr_impl_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
151+ {
152+ return LWP_MutexUnlock (*((mutex_t *)mutex));
153+ }
154+
155+ int __gthr_impl_recursive_mutex_destroy (__gthread_recursive_mutex_t *mutex)
156+ {
157+ return LWP_MutexDestroy (*((mutex_t *)mutex));
158+ }
159+
160+ void __gthr_impl_cond_init_function (__gthread_cond_t *__cond)
161+ {
162+ LWP_CondInit ((cond_t *)__cond);
163+ }
164+
165+ int __gthr_impl_cond_broadcast (__gthread_cond_t *__cond)
166+ {
167+ return LWP_CondBroadcast (*(cond_t *)__cond);
168+ }
169+
170+ int __gthr_impl_cond_signal (__gthread_cond_t *__cond)
171+ {
172+ return LWP_CondSignal (*(cond_t *)__cond);
173+ }
174+
175+ int __gthr_impl_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex)
176+ {
177+ return LWP_CondWait (*(cond_t *)__cond, *(mutex_t *)__mutex);
178+ }
179+
180+ int __gthr_impl_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex, const __gthread_time_t *__abs_timeout)
181+ {
182+ return LWP_CondTimedWait (*(cond_t *)__cond, *(mutex_t *)__mutex, __abs_timeout);
183+ }
184+
185+ int __gthr_impl_cond_wait_recursive (__gthread_cond_t *__cond, __gthread_recursive_mutex_t *__mutex)
186+ {
187+ return LWP_CondWait (*(cond_t *)__cond, *(mutex_t *)__mutex);
188+ }
189+
190+ int __gthr_impl_cond_destroy (__gthread_cond_t * __cond)
191+ {
192+ return LWP_CondDestroy (*(cond_t *)__cond);
193+ }
194+
195+ /* Dummy function required so that the linker doesn't strip this module */
196+ void __ogc_gthread_init () {}
197+ }
0 commit comments