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

4.115
Last change on this file since e72bc298 was e72bc298, checked in by Joel Sherrill <joel.sherrill@…>, on 07/01/10 at 15:37:48

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
RevLine 
[df49c60]1/*
[e72bc298]2 *  RTEMS threads compatibility routines for libgcc2.
[df49c60]3 *
[e72bc298]4 *  by: Rosimildo da Silva (rdasilva@connecttel.com)
[df49c60]5 *
[e72bc298]6 *  Used ideas from:
[df49c60]7 *    W. Eric Norum
8 *    Canadian Light Source
9 *    University of Saskatchewan
10 *    Saskatoon, Saskatchewan, CANADA
11 *    eric@cls.usask.ca
12 *
[e72bc298]13 *  Eric sent some e-mail in the rtems-list as a start point for this
14 *  module implementation.
[df49c60]15 *
[e72bc298]16 *  $Id$
[df49c60]17 */
18
[f49a82f3]19/*
20 * This file is only used if using gcc
21 */
22#if defined(__GNUC__)
23
[9c49db4]24#if HAVE_CONFIG_H
25#include "config.h"
26#endif
27
[df49c60]28#include <stdlib.h>
29#include <stdio.h>
30
31#include <rtems.h>
32#include <rtems/system.h>
[e72bc298]33#include <rtems/error.h>
[df49c60]34#include <rtems/rtems/tasks.h>
35
[e72bc298]36/* uncomment this if you need to debug this interface */
37/*#define DEBUG_GXX_WRAPPERS 1*/
38
[50f32b11]39/*
[df49c60]40 * These typedefs should match with the ones defined in the file
41 * gcc/gthr-rtems.h in the gcc distribution.
[64e442a]42 * FIXME: T.S, 2007/01/31: -> gcc/gthr-rtems.h still declares
43 *                            void * __gthread_key_t;
[df49c60]44 */
[64e442a]45typedef struct __gthread_key_ {
[e72bc298]46  void *val;             /* this is switched with the task      */
47  void (*dtor)(void*);   /* this remains in place for all tasks */
[64e442a]48} __gthread_key, *__gthread_key_t;
[e72bc298]49
[df49c60]50typedef int   __gthread_once_t;
51typedef void *__gthread_mutex_t;
[f49a82f3]52typedef void *__gthread_recursive_mutex_t;
[df49c60]53
[e72bc298]54int rtems_gxx_once(__gthread_once_t *once, void (*func) (void))
[df49c60]55{
[e72bc298]56  #ifdef DEBUG_GXX_WRAPPERS
57    printk( "gxx_wrappers: once=%x, func=%x\n", *once, func );
58  #endif
[df49c60]59
[e72bc298]60  if ( *(volatile __gthread_once_t *)once == 0 ) {
61    rtems_mode saveMode;
62    __gthread_once_t o;
[df49c60]63
[e72bc298]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;
[df49c60]73}
74
75int rtems_gxx_key_create (__gthread_key_t *key, void (*dtor) (void *))
76{
[e72bc298]77  rtems_status_code status;
78
[df49c60]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.
[ab660e77]81   * We have to to this, because the others functions on this interface
[df49c60]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. :-) */
[e72bc298]85  __gthread_key_t new_key = (__gthread_key_t) malloc( sizeof( *new_key ) );
[64e442a]86  *key = new_key;
87  new_key->val  = NULL;
88  new_key->dtor = dtor;
[df49c60]89
[e72bc298]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
[df49c60]96  /* register with RTEMS the buffer that will hold the key values */
[e72bc298]97  status = rtems_task_variable_add( RTEMS_SELF, (void **)new_key, dtor );
98  if ( status == RTEMS_SUCCESSFUL )
[45fcb76]99    return 0;
[df49c60]100  return -1;
101}
102
103int rtems_gxx_key_dtor (__gthread_key_t key, void *ptr)
104{
[e72bc298]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;
[df49c60]111}
112
113int rtems_gxx_key_delete (__gthread_key_t key)
114{
[e72bc298]115  rtems_status_code status;
116
117  #ifdef DEBUG_GXX_WRAPPERS
118    printk( "gxx_wrappers: delete key=%x\n", key );
119  #endif
120
[df49c60]121  /* register with RTEMS the buffer that will hold the key values */
[e72bc298]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;
[df49c60]127  }
128  return 0;
129}
130
131void *rtems_gxx_getspecific(__gthread_key_t key)
132{
[e72bc298]133  rtems_status_code  status;
134  void              *p= 0;
[df49c60]135
136  /* register with RTEMS the buffer that will hold the key values */
[e72bc298]137  status = rtems_task_variable_get( RTEMS_SELF, (void **)key, &p );
138  if ( status == RTEMS_SUCCESSFUL ) {
[df49c60]139    /* We do not have to do this, but what the heck ! */
[64e442a]140     p= key->val;
[e72bc298]141  } else {
[df49c60]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     */
[e72bc298]145    status = rtems_task_variable_add( RTEMS_SELF, (void **)key, key->dtor );
146    if ( status != RTEMS_SUCCESSFUL ) {
[6d135639]147       rtems_panic ("rtems_gxx_getspecific");
[df49c60]148    }
[64e442a]149    key->val = (void *)0;
[df49c60]150  }
151
[e72bc298]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;
[df49c60]161}
162
163int rtems_gxx_setspecific(__gthread_key_t key, const void *ptr)
164{
[e72bc298]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
[df49c60]176  /* register with RTEMS the buffer that will hold the key values */
[e72bc298]177  status = rtems_task_variable_add( RTEMS_SELF, (void **)key, key->dtor );
178  if ( status == RTEMS_SUCCESSFUL ) {
[df49c60]179    /* now let's set the proper value */
[64e442a]180    key->val =  (void *)ptr;
[e72bc298]181    return 0;
[df49c60]182  }
183  return -1;
184}
185
186
187/*
188 * MUTEX support
189 */
190void rtems_gxx_mutex_init (__gthread_mutex_t *mutex)
191{
[e72bc298]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");
[df49c60]215  }
[e72bc298]216  #ifdef DEBUG_GXX_WRAPPERS
217    printk( "gxx_wrappers: mutex init complete =%X\n", *mutex );
218  #endif
[df49c60]219}
220
221int rtems_gxx_mutex_lock (__gthread_mutex_t *mutex)
222{
[e72bc298]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;
[df49c60]237}
238
[8ac8cb2]239int rtems_gxx_mutex_destroy (__gthread_mutex_t *mutex)
240{
[e72bc298]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;
[8ac8cb2]251}
252
[df49c60]253int rtems_gxx_mutex_trylock (__gthread_mutex_t *mutex)
254{
[e72bc298]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;
[df49c60]265}
266
267int rtems_gxx_mutex_unlock (__gthread_mutex_t *mutex)
268{
[e72bc298]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;
[df49c60]279}
[f49a82f3]280
[6d1e301a]281void rtems_gxx_recursive_mutex_init(__gthread_recursive_mutex_t *mutex)
[f49a82f3]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.