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

4.11
Last change on this file since e72bc298 was e72bc298, checked in by Joel Sherrill <joel.sherrill@…>, on Jul 1, 2010 at 3:37:48 PM

2010-07-01 Joel Sherrill <joel.sherrill@…>

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