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