source: rtems/cpukit/libcsupport/src/gxx_wrappers.c @ c499856

4.115
Last change on this file since c499856 was 83bf105, checked in by Sebastian Huber <sebastian.huber@…>, on 02/19/14 at 09:57:46

score: Rename _Internal_error_Occurred()

Rename _Internal_error_Occurred() into _Terminate().

  • Property mode set to 100644
File size: 6.9 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief RTEMS Threads Compatibility Routines for Libgcc2
5 *  @ingroup GxxWrappersSupport
6 */
7
8/*
9 *  by: Rosimildo da Silva (rdasilva@connecttel.com)
10 *
11 *  Used ideas from:
12 *    W. Eric Norum
13 *    Canadian Light Source
14 *    University of Saskatchewan
15 *    Saskatoon, Saskatchewan, CANADA
16 *    eric@cls.usask.ca
17 *
18 *  Eric sent some e-mail in the rtems-list as a start point for this
19 *  module implementation.
20 */
21
22/*
23 * This file is only used if using gcc
24 */
25#if defined(__GNUC__)
26
27#if HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#include <rtems/gxx_wrappers.h>
32
33#include <stdlib.h>
34
35#include <rtems.h>
36
37/* uncomment this if you need to debug this interface */
38/*#define DEBUG_GXX_WRAPPERS 1*/
39
40int rtems_gxx_once(__gthread_once_t *once, void (*func) (void))
41{
42  #ifdef DEBUG_GXX_WRAPPERS
43    printk( "gxx_wrappers: once=%x, func=%x\n", *once, func );
44  #endif
45
46  if ( *(volatile __gthread_once_t *)once == 0 ) {
47    rtems_mode saveMode;
48    __gthread_once_t o;
49
50    rtems_task_mode(RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &saveMode);
51    if ( (o = *(volatile __gthread_once_t *)once) == 0 ) {
52      *(volatile __gthread_once_t *)once = 1;
53    }
54    rtems_task_mode(saveMode, RTEMS_PREEMPT_MASK, &saveMode);
55    if ( o == 0 )
56      (*func)();
57  }
58  return 0;
59}
60
61int rtems_gxx_key_create (__gthread_key_t *key, void (*dtor) (void *))
62{
63  rtems_status_code status;
64
65  /* Ok, this can be a bit tricky. We are going to return a "key" as a
66   * pointer to the buffer that will hold the value of the key itself.
67   * We have to to this, because the others functions on this interface
68   * deal with the value of the key, as used with the POSIX API.
69   */
70   /* Do not pull your hair, trust me this works. :-) */
71  __gthread_key_t new_key = (__gthread_key_t) malloc( sizeof( *new_key ) );
72  *key = new_key;
73  new_key->val  = NULL;
74  new_key->dtor = dtor;
75
76  #ifdef DEBUG_GXX_WRAPPERS
77    printk(
78      "gxx_wrappers: create key=%x, dtor=%x, new_key=%x\n", key, dtor, new_key
79    );
80  #endif
81
82  /* register with RTEMS the buffer that will hold the key values */
83  status = rtems_task_variable_add( RTEMS_SELF, (void **)new_key, dtor );
84  if ( status == RTEMS_SUCCESSFUL )
85    return 0;
86
87  free( new_key );
88  return -1;
89}
90
91int rtems_gxx_key_dtor (__gthread_key_t key, void *ptr)
92{
93  #ifdef DEBUG_GXX_WRAPPERS
94    printk( "gxx_wrappers: dtor key=%x, ptr=%x\n", key, ptr );
95  #endif
96
97  key->val  = 0;
98  return 0;
99}
100
101int rtems_gxx_key_delete (__gthread_key_t key)
102{
103  rtems_status_code status;
104
105  #ifdef DEBUG_GXX_WRAPPERS
106    printk( "gxx_wrappers: delete key=%x\n", key );
107  #endif
108
109  /* register with RTEMS the buffer that will hold the key values */
110  status = rtems_task_variable_delete( RTEMS_SELF, (void **)key );
111  if ( status == RTEMS_SUCCESSFUL ) {
112    /* Hmm - hopefully all tasks using this key have gone away... */
113    if ( key ) free( *(void **)key );
114    return 0;
115  }
116  key = NULL;
117  return 0;
118}
119
120void *rtems_gxx_getspecific(__gthread_key_t key)
121{
122  rtems_status_code  status;
123  void              *p= 0;
124
125  /* register with RTEMS the buffer that will hold the key values */
126  status = rtems_task_variable_get( RTEMS_SELF, (void **)key, &p );
127  if ( status == RTEMS_SUCCESSFUL ) {
128    /* We do not have to do this, but what the heck ! */
129     p= key->val;
130  } else {
131    /* fisrt time, always set to zero, it is unknown the value that the others
132     * threads are using at the moment of this call
133     */
134    status = rtems_task_variable_add( RTEMS_SELF, (void **)key, key->dtor );
135    if ( status != RTEMS_SUCCESSFUL ) {
136      _Terminate(
137        INTERNAL_ERROR_CORE,
138        true,
139        INTERNAL_ERROR_GXX_KEY_ADD_FAILED
140      );
141    }
142    key->val = (void *)0;
143  }
144
145  #ifdef DEBUG_GXX_WRAPPERS
146    printk(
147      "gxx_wrappers: getspecific key=%x, ptr=%x, id=%x\n",
148       key,
149       p,
150       rtems_task_self()
151    );
152  #endif
153  return p;
154}
155
156int rtems_gxx_setspecific(__gthread_key_t key, const void *ptr)
157{
158  rtems_status_code status;
159
160  #ifdef DEBUG_GXX_WRAPPERS
161    printk(
162      "gxx_wrappers: setspecific key=%x, ptr=%x, id=%x\n",
163      key,
164      ptr,
165      rtems_task_self()
166      );
167  #endif
168
169  /* register with RTEMS the buffer that will hold the key values */
170  status = rtems_task_variable_add( RTEMS_SELF, (void **)key, key->dtor );
171  if ( status == RTEMS_SUCCESSFUL ) {
172    /* now let's set the proper value */
173    key->val =  (void *)ptr;
174    return 0;
175  }
176  return -1;
177}
178
179
180/*
181 * MUTEX support
182 */
183void rtems_gxx_mutex_init (__gthread_mutex_t *mutex)
184{
185  rtems_status_code status;
186
187  #ifdef DEBUG_GXX_WRAPPERS
188    printk( "gxx_wrappers: mutex init =%X\n", *mutex );
189  #endif
190
191  status = rtems_semaphore_create(
192    rtems_build_name ('G', 'C', 'C', '2'),
193    1,
194    RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE|
195      RTEMS_INHERIT_PRIORITY|RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL,
196    0,
197    (rtems_id *)mutex
198  );
199  if ( status != RTEMS_SUCCESSFUL ) {
200    #ifdef DEBUG_GXX_WRAPPERS
201      printk(
202        "gxx_wrappers: mutex init failed %s (%d)\n",
203        rtems_status_text(status),
204        status
205      );
206    #endif
207    _Terminate(
208      INTERNAL_ERROR_CORE,
209      true,
210      INTERNAL_ERROR_GXX_MUTEX_INIT_FAILED
211    );
212  }
213  #ifdef DEBUG_GXX_WRAPPERS
214    printk( "gxx_wrappers: mutex init complete =%X\n", *mutex );
215  #endif
216}
217
218int rtems_gxx_mutex_lock (__gthread_mutex_t *mutex)
219{
220  rtems_status_code status;
221
222  #ifdef DEBUG_GXX_WRAPPERS
223    printk( "gxx_wrappers: lock mutex=%X\n", *mutex );
224  #endif
225
226  status = rtems_semaphore_obtain(
227    *(rtems_id *)mutex,
228    RTEMS_WAIT,
229    RTEMS_NO_TIMEOUT
230  );
231  if ( status == RTEMS_SUCCESSFUL )
232    return 0;
233  return -1;
234}
235
236int rtems_gxx_mutex_destroy (__gthread_mutex_t *mutex)
237{
238  rtems_status_code status;
239
240  #ifdef DEBUG_GXX_WRAPPERS
241    printk( "gxx_wrappers: destroy mutex=%X\n", *mutex );
242  #endif
243
244  status = rtems_semaphore_delete(*(rtems_id *)mutex);
245  if ( status == RTEMS_SUCCESSFUL )
246    return 0;
247  return -1;
248}
249
250int rtems_gxx_mutex_trylock (__gthread_mutex_t *mutex)
251{
252  rtems_status_code status;
253
254  #ifdef DEBUG_GXX_WRAPPERS
255    printk( "gxx_wrappers: trylock mutex=%X\n", *mutex );
256  #endif
257
258  status = rtems_semaphore_obtain (*(rtems_id *)mutex, RTEMS_NO_WAIT, 0);
259  if ( status == RTEMS_SUCCESSFUL )
260    return 0;
261  return -1;
262}
263
264int rtems_gxx_mutex_unlock (__gthread_mutex_t *mutex)
265{
266  rtems_status_code status;
267
268  #ifdef DEBUG_GXX_WRAPPERS
269    printk( "gxx_wrappers: unlock mutex=%X\n", *mutex );
270  #endif
271
272  status = rtems_semaphore_release( *(rtems_id *)mutex );
273  if ( status == RTEMS_SUCCESSFUL )
274    return 0;
275  return -1;
276}
277
278void rtems_gxx_recursive_mutex_init(__gthread_recursive_mutex_t *mutex)
279{
280  rtems_gxx_mutex_init(mutex);
281}
282
283int rtems_gxx_recursive_mutex_lock(__gthread_recursive_mutex_t *mutex)
284{
285  return rtems_gxx_mutex_lock(mutex);
286}
287
288int rtems_gxx_recursive_mutex_trylock(__gthread_recursive_mutex_t *mutex)
289{
290  return rtems_gxx_mutex_trylock(mutex);
291}
292
293int rtems_gxx_recursive_mutex_unlock(__gthread_recursive_mutex_t *mutex)
294{
295  return rtems_gxx_mutex_unlock(mutex);
296}
297
298#endif /* __GNUC__ */
Note: See TracBrowser for help on using the repository browser.