source: rtems/cpukit/libcsupport/src/gxx_wrappers.c @ 972a8dba

4.115
Last change on this file since 972a8dba was cb87694, checked in by Joel Sherrill <joel.sherrill@…>, on 07/25/10 at 14:52:27

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

  • libcsupport/src/gxx_wrappers.c: Free contents of key not key itself. Kye pointer will never be malloc'ed.
  • 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  key = NULL;
129  return 0;
130}
131
132void *rtems_gxx_getspecific(__gthread_key_t key)
133{
134  rtems_status_code  status;
135  void              *p= 0;
136
137  /* register with RTEMS the buffer that will hold the key values */
138  status = rtems_task_variable_get( RTEMS_SELF, (void **)key, &p );
139  if ( status == RTEMS_SUCCESSFUL ) {
140    /* We do not have to do this, but what the heck ! */
141     p= key->val;
142  } else {
143    /* fisrt time, always set to zero, it is unknown the value that the others
144     * threads are using at the moment of this call
145     */
146    status = rtems_task_variable_add( RTEMS_SELF, (void **)key, key->dtor );
147    if ( status != RTEMS_SUCCESSFUL ) {
148       rtems_panic ("rtems_gxx_getspecific");
149    }
150    key->val = (void *)0;
151  }
152
153  #ifdef DEBUG_GXX_WRAPPERS
154    printk(
155      "gxx_wrappers: getspecific key=%x, ptr=%x, id=%x\n",
156       key,
157       p,
158       rtems_task_self()
159    );
160  #endif
161  return p;
162}
163
164int rtems_gxx_setspecific(__gthread_key_t key, const void *ptr)
165{
166  rtems_status_code status;
167
168  #ifdef DEBUG_GXX_WRAPPERS
169    printk(
170      "gxx_wrappers: setspecific key=%x, ptr=%x, id=%x\n",
171      key,
172      ptr,
173      rtems_task_self()
174      );
175  #endif
176
177  /* register with RTEMS the buffer that will hold the key values */
178  status = rtems_task_variable_add( RTEMS_SELF, (void **)key, key->dtor );
179  if ( status == RTEMS_SUCCESSFUL ) {
180    /* now let's set the proper value */
181    key->val =  (void *)ptr;
182    return 0;
183  }
184  return -1;
185}
186
187
188/*
189 * MUTEX support
190 */
191void rtems_gxx_mutex_init (__gthread_mutex_t *mutex)
192{
193  rtems_status_code status;
194
195  #ifdef DEBUG_GXX_WRAPPERS
196    printk( "gxx_wrappers: mutex init =%X\n", *mutex );
197  #endif
198
199  status = rtems_semaphore_create(
200    rtems_build_name ('G', 'C', 'C', '2'),
201    1,
202    RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE|
203      RTEMS_INHERIT_PRIORITY|RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL,
204    0,
205    (rtems_id *)mutex
206  );
207  if ( status != RTEMS_SUCCESSFUL ) {
208    #ifdef DEBUG_GXX_WRAPPERS
209      printk(
210        "gxx_wrappers: mutex init failed %s (%d)\n",
211        rtems_status_text(status),
212        status
213      );
214    #endif
215    rtems_panic ("rtems_gxx_mutex_init");
216  }
217  #ifdef DEBUG_GXX_WRAPPERS
218    printk( "gxx_wrappers: mutex init complete =%X\n", *mutex );
219  #endif
220}
221
222int rtems_gxx_mutex_lock (__gthread_mutex_t *mutex)
223{
224  rtems_status_code status;
225
226  #ifdef DEBUG_GXX_WRAPPERS
227    printk( "gxx_wrappers: lock mutex=%X\n", *mutex );
228  #endif
229
230  status = rtems_semaphore_obtain(
231    *(rtems_id *)mutex,
232    RTEMS_WAIT,
233    RTEMS_NO_TIMEOUT
234  );
235  if ( status == RTEMS_SUCCESSFUL )
236    return 0;
237  return -1;
238}
239
240int rtems_gxx_mutex_destroy (__gthread_mutex_t *mutex)
241{
242  rtems_status_code status;
243
244  #ifdef DEBUG_GXX_WRAPPERS
245    printk( "gxx_wrappers: destroy mutex=%X\n", *mutex );
246  #endif
247
248  status = rtems_semaphore_delete(*(rtems_id *)mutex);
249  if ( status == RTEMS_SUCCESSFUL )
250    return 0;
251  return -1;
252}
253
254int rtems_gxx_mutex_trylock (__gthread_mutex_t *mutex)
255{
256  rtems_status_code status;
257
258  #ifdef DEBUG_GXX_WRAPPERS
259    printk( "gxx_wrappers: trylock mutex=%X\n", *mutex );
260  #endif
261
262  status = rtems_semaphore_obtain (*(rtems_id *)mutex, RTEMS_NO_WAIT, 0);
263  if ( status == RTEMS_SUCCESSFUL )
264    return 0;
265  return -1;
266}
267
268int rtems_gxx_mutex_unlock (__gthread_mutex_t *mutex)
269{
270  rtems_status_code status;
271
272  #ifdef DEBUG_GXX_WRAPPERS
273    printk( "gxx_wrappers: unlock mutex=%X\n", *mutex );
274  #endif
275
276  status = rtems_semaphore_release( *(rtems_id *)mutex );
277  if ( status == RTEMS_SUCCESSFUL )
278    return 0;
279  return -1;
280}
281
282void rtems_gxx_recursive_mutex_init(__gthread_recursive_mutex_t *mutex)
283{
284  rtems_gxx_mutex_init(mutex);
285}
286
287int rtems_gxx_recursive_mutex_lock(__gthread_recursive_mutex_t *mutex)
288{
289  return rtems_gxx_mutex_lock(mutex);
290}
291
292int rtems_gxx_recursive_mutex_trylock(__gthread_recursive_mutex_t *mutex)
293{
294  return rtems_gxx_mutex_trylock(mutex);
295}
296
297int rtems_gxx_recursive_mutex_unlock(__gthread_recursive_mutex_t *mutex)
298{
299  return rtems_gxx_mutex_unlock(mutex);
300}
301
302#endif /* __GNUC__ */
Note: See TracBrowser for help on using the repository browser.