1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | #if defined(__GNUC__4) |
23 | |
24 | #if HAVE_CONFIG_H1 |
25 | #include "config.h" |
26 | #endif |
27 | |
28 | #include <rtems/gxx_wrappers.h> |
29 | |
30 | #include <stdlib.h> |
31 | |
32 | #include <rtems.h> |
33 | |
34 | |
35 | |
36 | |
37 | int rtems_gxx_once(__gthread_once_t *once, void (*func) (void)) |
38 | { |
39 | #ifdef DEBUG_GXX_WRAPPERS |
40 | printk( "gxx_wrappers: once=%x, func=%x\n", *once, func ); |
41 | #endif |
42 | |
43 | if ( *(volatile __gthread_once_t *)once == 0 ) { |
44 | rtems_mode saveMode; |
45 | __gthread_once_t o; |
46 | |
47 | rtems_task_mode(RTEMS_NO_PREEMPT0x00000100, RTEMS_PREEMPT_MASK0x00000100, &saveMode); |
48 | if ( (o = *(volatile __gthread_once_t *)once) == 0 ) { |
49 | *(volatile __gthread_once_t *)once = 1; |
50 | } |
51 | rtems_task_mode(saveMode, RTEMS_PREEMPT_MASK0x00000100, &saveMode); |
52 | if ( o == 0 ) |
53 | (*func)(); |
54 | } |
55 | return 0; |
56 | } |
57 | |
58 | int rtems_gxx_key_create (__gthread_key_t *key, void (*dtor) (void *)) |
59 | { |
60 | rtems_status_code status; |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | __gthread_key_t new_key = (__gthread_key_t) malloc( sizeof( *new_key ) ); |
69 | *key = new_key; |
70 | new_key->val = NULL((void*)0); |
71 | new_key->dtor = dtor; |
72 | |
73 | #ifdef DEBUG_GXX_WRAPPERS |
74 | printk( |
75 | "gxx_wrappers: create key=%x, dtor=%x, new_key=%x\n", key, dtor, new_key |
76 | ); |
77 | #endif |
78 | |
79 | |
80 | status = rtems_task_variable_add( RTEMS_SELF((Objects_Id) 0), (void **)new_key, dtor ); |
81 | if ( status == RTEMS_SUCCESSFUL ) |
| |
82 | return 0; |
| 2 | Allocated memory never released. Potential memory leak |
|
83 | return -1; |
84 | } |
85 | |
86 | int rtems_gxx_key_dtor (__gthread_key_t key, void *ptr) |
87 | { |
88 | #ifdef DEBUG_GXX_WRAPPERS |
89 | printk( "gxx_wrappers: dtor key=%x, ptr=%x\n", key, ptr ); |
90 | #endif |
91 | |
92 | key->val = 0; |
93 | return 0; |
94 | } |
95 | |
96 | int rtems_gxx_key_delete (__gthread_key_t key) |
97 | { |
98 | rtems_status_code status; |
99 | |
100 | #ifdef DEBUG_GXX_WRAPPERS |
101 | printk( "gxx_wrappers: delete key=%x\n", key ); |
102 | #endif |
103 | |
104 | |
105 | status = rtems_task_variable_delete( RTEMS_SELF((Objects_Id) 0), (void **)key ); |
106 | if ( status == RTEMS_SUCCESSFUL ) { |
107 | |
108 | if ( key ) free( *(void **)key ); |
109 | return 0; |
110 | } |
111 | key = NULL((void*)0); |
112 | return 0; |
113 | } |
114 | |
115 | void *rtems_gxx_getspecific(__gthread_key_t key) |
116 | { |
117 | rtems_status_code status; |
118 | void *p= 0; |
119 | |
120 | |
121 | status = rtems_task_variable_get( RTEMS_SELF((Objects_Id) 0), (void **)key, &p ); |
122 | if ( status == RTEMS_SUCCESSFUL ) { |
123 | |
124 | p= key->val; |
125 | } else { |
126 | |
127 | |
128 | |
129 | status = rtems_task_variable_add( RTEMS_SELF((Objects_Id) 0), (void **)key, key->dtor ); |
130 | if ( status != RTEMS_SUCCESSFUL ) { |
131 | _Internal_error_Occurred( |
132 | INTERNAL_ERROR_CORE, |
133 | true1, |
134 | INTERNAL_ERROR_GXX_KEY_ADD_FAILED |
135 | ); |
136 | } |
137 | key->val = (void *)0; |
138 | } |
139 | |
140 | #ifdef DEBUG_GXX_WRAPPERS |
141 | printk( |
142 | "gxx_wrappers: getspecific key=%x, ptr=%x, id=%x\n", |
143 | key, |
144 | p, |
145 | rtems_task_self() |
146 | ); |
147 | #endif |
148 | return p; |
149 | } |
150 | |
151 | int rtems_gxx_setspecific(__gthread_key_t key, const void *ptr) |
152 | { |
153 | rtems_status_code status; |
154 | |
155 | #ifdef DEBUG_GXX_WRAPPERS |
156 | printk( |
157 | "gxx_wrappers: setspecific key=%x, ptr=%x, id=%x\n", |
158 | key, |
159 | ptr, |
160 | rtems_task_self() |
161 | ); |
162 | #endif |
163 | |
164 | |
165 | status = rtems_task_variable_add( RTEMS_SELF((Objects_Id) 0), (void **)key, key->dtor ); |
166 | if ( status == RTEMS_SUCCESSFUL ) { |
167 | |
168 | key->val = (void *)ptr; |
169 | return 0; |
170 | } |
171 | return -1; |
172 | } |
173 | |
174 | |
175 | |
176 | |
177 | |
178 | void rtems_gxx_mutex_init (__gthread_mutex_t *mutex) |
179 | { |
180 | rtems_status_code status; |
181 | |
182 | #ifdef DEBUG_GXX_WRAPPERS |
183 | printk( "gxx_wrappers: mutex init =%X\n", *mutex ); |
184 | #endif |
185 | |
186 | status = rtems_semaphore_create( |
187 | rtems_build_name ('G', 'C', 'C', '2')( (uint32_t)('G') << 24 | (uint32_t)('C') << 16 | (uint32_t)('C') << 8 | (uint32_t)('2') ), |
188 | 1, |
189 | RTEMS_PRIORITY0x00000004|RTEMS_BINARY_SEMAPHORE0x00000010| |
190 | RTEMS_INHERIT_PRIORITY0x00000040|RTEMS_NO_PRIORITY_CEILING0x00000000|RTEMS_LOCAL0x00000000, |
191 | 0, |
192 | (rtems_id *)mutex |
193 | ); |
194 | if ( status != RTEMS_SUCCESSFUL ) { |
195 | #ifdef DEBUG_GXX_WRAPPERS |
196 | printk( |
197 | "gxx_wrappers: mutex init failed %s (%d)\n", |
198 | rtems_status_text(status), |
199 | status |
200 | ); |
201 | #endif |
202 | _Internal_error_Occurred( |
203 | INTERNAL_ERROR_CORE, |
204 | true1, |
205 | INTERNAL_ERROR_GXX_MUTEX_INIT_FAILED |
206 | ); |
207 | } |
208 | #ifdef DEBUG_GXX_WRAPPERS |
209 | printk( "gxx_wrappers: mutex init complete =%X\n", *mutex ); |
210 | #endif |
211 | } |
212 | |
213 | int rtems_gxx_mutex_lock (__gthread_mutex_t *mutex) |
214 | { |
215 | rtems_status_code status; |
216 | |
217 | #ifdef DEBUG_GXX_WRAPPERS |
218 | printk( "gxx_wrappers: lock mutex=%X\n", *mutex ); |
219 | #endif |
220 | |
221 | status = rtems_semaphore_obtain( |
222 | *(rtems_id *)mutex, |
223 | RTEMS_WAIT0x00000000, |
224 | RTEMS_NO_TIMEOUT0 |
225 | ); |
226 | if ( status == RTEMS_SUCCESSFUL ) |
227 | return 0; |
228 | return -1; |
229 | } |
230 | |
231 | int rtems_gxx_mutex_destroy (__gthread_mutex_t *mutex) |
232 | { |
233 | rtems_status_code status; |
234 | |
235 | #ifdef DEBUG_GXX_WRAPPERS |
236 | printk( "gxx_wrappers: destroy mutex=%X\n", *mutex ); |
237 | #endif |
238 | |
239 | status = rtems_semaphore_delete(*(rtems_id *)mutex); |
240 | if ( status == RTEMS_SUCCESSFUL ) |
241 | return 0; |
242 | return -1; |
243 | } |
244 | |
245 | int rtems_gxx_mutex_trylock (__gthread_mutex_t *mutex) |
246 | { |
247 | rtems_status_code status; |
248 | |
249 | #ifdef DEBUG_GXX_WRAPPERS |
250 | printk( "gxx_wrappers: trylock mutex=%X\n", *mutex ); |
251 | #endif |
252 | |
253 | status = rtems_semaphore_obtain (*(rtems_id *)mutex, RTEMS_NO_WAIT0x00000001, 0); |
254 | if ( status == RTEMS_SUCCESSFUL ) |
255 | return 0; |
256 | return -1; |
257 | } |
258 | |
259 | int rtems_gxx_mutex_unlock (__gthread_mutex_t *mutex) |
260 | { |
261 | rtems_status_code status; |
262 | |
263 | #ifdef DEBUG_GXX_WRAPPERS |
264 | printk( "gxx_wrappers: unlock mutex=%X\n", *mutex ); |
265 | #endif |
266 | |
267 | status = rtems_semaphore_release( *(rtems_id *)mutex ); |
268 | if ( status == RTEMS_SUCCESSFUL ) |
269 | return 0; |
270 | return -1; |
271 | } |
272 | |
273 | void rtems_gxx_recursive_mutex_init(__gthread_recursive_mutex_t *mutex) |
274 | { |
275 | rtems_gxx_mutex_init(mutex); |
276 | } |
277 | |
278 | int rtems_gxx_recursive_mutex_lock(__gthread_recursive_mutex_t *mutex) |
279 | { |
280 | return rtems_gxx_mutex_lock(mutex); |
281 | } |
282 | |
283 | int rtems_gxx_recursive_mutex_trylock(__gthread_recursive_mutex_t *mutex) |
284 | { |
285 | return rtems_gxx_mutex_trylock(mutex); |
286 | } |
287 | |
288 | int rtems_gxx_recursive_mutex_unlock(__gthread_recursive_mutex_t *mutex) |
289 | { |
290 | return rtems_gxx_mutex_unlock(mutex); |
291 | } |
292 | |
293 | #endif /* __GNUC__ */ |