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, __OGC_ONCE_STARTED, false , __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) {
97+ __func ();
98+ __atomic_store_n ((uint32_t *)__once, __OGC_ONCE_DONE, __ATOMIC_RELEASE);
99+ } else if (expected != __OGC_ONCE_DONE) {
100+ do {
101+ __atomic_load ((uint32_t *)__once, &expected, __ATOMIC_ACQUIRE);
102+ } while (expected != __OGC_ONCE_DONE);
103+ }
104+
105+ return 0 ;
106+ }
107+
108+ void __gthr_impl_mutex_init_function (__gthread_mutex_t *mutex)
109+ {
110+ LWP_MutexInit (((mutex_t *)mutex), false );
111+ }
112+
113+ int __gthr_impl_mutex_lock (__gthread_mutex_t *mutex)
114+ {
115+ return LWP_MutexLock (*((mutex_t *)mutex));
116+ }
117+
118+ int __gthr_impl_mutex_trylock (__gthread_mutex_t *mutex)
119+ {
120+ return LWP_MutexTryLock (*((mutex_t *)mutex));
121+ }
122+
123+ int __gthr_impl_mutex_unlock (__gthread_mutex_t *mutex)
124+ {
125+ return LWP_MutexUnlock (*((mutex_t *)mutex));
126+ }
127+
128+ int __gthr_impl_mutex_destroy (__gthread_mutex_t *mutex)
129+ {
130+ return LWP_MutexDestroy (*((mutex_t *)mutex));
131+ }
132+
133+ int __gthr_impl_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
134+ {
135+ return LWP_MutexInit (((mutex_t *)mutex), true );
136+ }
137+
138+ int __gthr_impl_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
139+ {
140+ return LWP_MutexLock (*((mutex_t *)mutex));
141+ }
142+
143+ int __gthr_impl_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
144+ {
145+ return LWP_MutexTryLock (*((mutex_t *)mutex));
146+ }
147+
148+ int __gthr_impl_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
149+ {
150+ return LWP_MutexUnlock (*((mutex_t *)mutex));
151+ }
152+
153+ int __gthr_impl_recursive_mutex_destroy (__gthread_recursive_mutex_t *mutex)
154+ {
155+ return LWP_MutexDestroy (*((mutex_t *)mutex));
156+ }
157+
158+ void __gthr_impl_cond_init_function (__gthread_cond_t *__cond)
159+ {
160+ LWP_CondInit ((cond_t *)__cond);
161+ }
162+
163+ int __gthr_impl_cond_broadcast (__gthread_cond_t *__cond)
164+ {
165+ return LWP_CondBroadcast (*(cond_t *)__cond);
166+ }
167+
168+ int __gthr_impl_cond_signal (__gthread_cond_t *__cond)
169+ {
170+ return LWP_CondSignal (*(cond_t *)__cond);
171+ }
172+
173+ int __gthr_impl_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex)
174+ {
175+ return LWP_CondWait (*(cond_t *)__cond, *(mutex_t *)__mutex);
176+ }
177+
178+ int __gthr_impl_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex, const __gthread_time_t *__abs_timeout)
179+ {
180+ return LWP_CondTimedWait (*(cond_t *)__cond, *(mutex_t *)__mutex, __abs_timeout);
181+ }
182+
183+ int __gthr_impl_cond_wait_recursive (__gthread_cond_t *__cond, __gthread_recursive_mutex_t *__mutex)
184+ {
185+ return LWP_CondWait (*(cond_t *)__cond, *(mutex_t *)__mutex);
186+ }
187+
188+ int __gthr_impl_cond_destroy (__gthread_cond_t * __cond)
189+ {
190+ return LWP_CondDestroy (*(cond_t *)__cond);
191+ }
192+
193+ /* Dummy function required so that the linker doesn't strip this module */
194+ void __ogc_gthread_init () {}
195+ }
0 commit comments