source: rtems/cpukit/libcsupport/src/gxx_wrappers.c @ 4a2fee47

Last change on this file since 4a2fee47 was 4a2fee47, checked in by Till Straumann <strauman@…>, on 02/06/07 at 22:54:34

2007-02-06 Till Straumann <strauman@…>

  • libcsupport/src/gxx_wrappers.c: fix PR#690. Supply taskvar dtor to plug memory leak. Applied patch attached to PR#690.
  • Property mode set to 100644
File size: 6.7 KB
RevLine 
[df49c60]1/*
2 * RTEMS threads compatibily 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 *
[ab660e77]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/* We might not need, defined just in case */
29#define  __RTEMS_INSIDE__  1
30
31
32#include <stdlib.h>
33#include <stdio.h>
34
35#include <rtems.h>
36#include <rtems/system.h>
[c4477581]37#include <rtems/error.h>        /* rtems_panic */
[df49c60]38#include <rtems/rtems/tasks.h>
39
[50f32b11]40/*
[df49c60]41 * These typedefs should match with the ones defined in the file
42 * gcc/gthr-rtems.h in the gcc distribution.
[4a2fee47]43 * FIXME: T.S, 2007/01/31: -> gcc/gthr-rtems.h still declares
44 *                            void * __gthread_key_t;
[df49c60]45 */
[4a2fee47]46typedef struct __gthread_key_ {
47        void *val;                 /* this is switched with the task      */
48        void (*dtor)(void*);   /* this remains in place for all tasks */
49} __gthread_key, *__gthread_key_t;
[df49c60]50typedef int   __gthread_once_t;
51typedef void *__gthread_mutex_t;
[f49a82f3]52typedef void *__gthread_recursive_mutex_t;
[df49c60]53
54/* uncomment this if you need to debug this interface */
55
56/*
57#define DEBUG_GXX_WRAPPERS 1
58*/
59
60#ifdef DEBUG_GXX_WRAPPERS
61/* local function to return the ID of the calling thread */
62static rtems_id get_tid( void )
63{
[50f32b11]64   rtems_id id = 0;
[df49c60]65   rtems_task_ident( RTEMS_SELF, 0, &id );
66   return id;
67}
68#endif
69
70
[616b9f5]71int rtems_gxx_once(__gthread_once_t *once, void (*func) (void))
[df49c60]72{
73#ifdef DEBUG_GXX_WRAPPERS
74   printk( "gxx_wrappers: once=%x, func=%x\n", *once, func );
75#endif
[49155d9]76   if( *(volatile __gthread_once_t *)once == 0 )
[df49c60]77   {
[49155d9]78      rtems_mode saveMode;
[4a2fee47]79      __gthread_once_t o;
[49155d9]80      rtems_task_mode(RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &saveMode);
[4a2fee47]81      if( (o = *(volatile __gthread_once_t *)once) == 0 )
[49155d9]82      {
83         *(volatile __gthread_once_t *)once = 1;
84      }
85      rtems_task_mode(saveMode, RTEMS_PREEMPT_MASK, &saveMode);
[4a2fee47]86      if ( o == 0 )
87         (*func)();
[df49c60]88   }
89   return 0;
90}
91
92
93int rtems_gxx_key_create (__gthread_key_t *key, void (*dtor) (void *))
94{
95  /* Ok, this can be a bit tricky. We are going to return a "key" as a
96   * pointer to the buffer that will hold the value of the key itself.
[ab660e77]97   * We have to to this, because the others functions on this interface
[df49c60]98   * deal with the value of the key, as used with the POSIX API.
99   */
100   /* Do not pull your hair, trust me this works. :-) */
[4a2fee47]101  __gthread_key_t new_key = ( __gthread_key_t )malloc( sizeof( *new_key ) );
102  *key = new_key;
103  new_key->val  = NULL;
104  new_key->dtor = dtor;
[df49c60]105
106#ifdef DEBUG_GXX_WRAPPERS
107  printk( "gxx_wrappers: create key=%x, dtor=%x, new_key=%x\n", key, dtor, new_key );
108#endif
109  /* register with RTEMS the buffer that will hold the key values */
[4a2fee47]110  if( rtems_task_variable_add( RTEMS_SELF, (void **)new_key, dtor ) == RTEMS_SUCCESSFUL )
[df49c60]111       return 0;
112  return -1;
113}
114
115int rtems_gxx_key_dtor (__gthread_key_t key, void *ptr)
116{
117#ifdef DEBUG_GXX_WRAPPERS
118  printk( "gxx_wrappers: dtor key=%x, ptr=%x\n", key, ptr );
119#endif
[4a2fee47]120   key->val  = 0;
[df49c60]121   return 0;
122}
123
124int rtems_gxx_key_delete (__gthread_key_t key)
125{
126#ifdef DEBUG_GXX_WRAPPERS
127  printk( "gxx_wrappers: delete key=%x\n", key );
128#endif
129  /* register with RTEMS the buffer that will hold the key values */
130  if( rtems_task_variable_delete( RTEMS_SELF, (void **)key ) == RTEMS_SUCCESSFUL )
131  {
[4a2fee47]132     /* Hmm - hopefully all tasks using this key have gone away... */
[df49c60]133     if( key ) free( (void *)key );
134     return 0;
135  }
136  return 0;
137}
138
139
140void *rtems_gxx_getspecific(__gthread_key_t key)
141{
142  void *p= 0;
143
144  /* register with RTEMS the buffer that will hold the key values */
145  if( rtems_task_variable_get( RTEMS_SELF, (void **)key, &p ) == RTEMS_SUCCESSFUL )
146  {
147    /* We do not have to do this, but what the heck ! */
[4a2fee47]148     p= key->val;
[df49c60]149  }
150  else
151  {
152    /* fisrt time, always set to zero, it is unknown the value that the others
153     * threads are using at the moment of this call
154     */
[4a2fee47]155    if( rtems_task_variable_add( RTEMS_SELF, (void **)key, key->dtor ) != RTEMS_SUCCESSFUL )
[df49c60]156    {
[6d135639]157       rtems_panic ("rtems_gxx_getspecific");
[df49c60]158    }
[4a2fee47]159    key->val = (void *)0;
[df49c60]160  }
161
162#ifdef DEBUG_GXX_WRAPPERS
163   printk( "gxx_wrappers: getspecific key=%x, ptr=%x, id=%x\n", key, p, get_tid() );
164#endif
165   return p;
166}
167
168
169int rtems_gxx_setspecific(__gthread_key_t key, const void *ptr)
170{
171#ifdef DEBUG_GXX_WRAPPERS
172  printk( "gxx_wrappers: setspecific key=%x, ptr=%x, id=%x\n", key, ptr, get_tid() );
173#endif
174  /* register with RTEMS the buffer that will hold the key values */
[4a2fee47]175  if( rtems_task_variable_add( RTEMS_SELF, (void **)key, key->dtor ) == RTEMS_SUCCESSFUL )
[df49c60]176  {
177    /* now let's set the proper value */
[4a2fee47]178    key->val =  (void *)ptr;
[df49c60]179     return 0;
180  }
181  return -1;
182}
183
184
185/*
186 * MUTEX support
187 */
188void rtems_gxx_mutex_init (__gthread_mutex_t *mutex)
189{
190#ifdef DEBUG_GXX_WRAPPERS
191  printk( "gxx_wrappers: mutex init =%X\n", *mutex );
192#endif
193  if( rtems_semaphore_create( rtems_build_name ('G', 'C', 'C', '2'),
194                              1,
195                             RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE
196                             |RTEMS_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL,
197                             0,
198                             (rtems_id *)mutex ) != RTEMS_SUCCESSFUL )
199  {
[6d135639]200      rtems_panic ("rtems_gxx_mutex_init");
[df49c60]201  }
202#ifdef DEBUG_GXX_WRAPPERS
203  printk( "gxx_wrappers: mutex init complete =%X\n", *mutex );
204#endif
205}
206
207int rtems_gxx_mutex_lock (__gthread_mutex_t *mutex)
208{
209#ifdef DEBUG_GXX_WRAPPERS
210  printk( "gxx_wrappers: lock mutex=%X\n", *mutex );
211#endif
[50f32b11]212  return ( rtems_semaphore_obtain( (rtems_id)*mutex,
[df49c60]213            RTEMS_WAIT, RTEMS_NO_TIMEOUT ) ==  RTEMS_SUCCESSFUL) ? 0 : -1;
214}
215
216int rtems_gxx_mutex_trylock (__gthread_mutex_t *mutex)
217{
218#ifdef DEBUG_GXX_WRAPPERS
219  printk( "gxx_wrappers: trylock mutex=%X\n", *mutex );
220#endif
[50f32b11]221  return (rtems_semaphore_obtain ((rtems_id)*mutex,
[df49c60]222               RTEMS_NO_WAIT, 0) == RTEMS_SUCCESSFUL) ? 0 : -1;
223}
224
225int rtems_gxx_mutex_unlock (__gthread_mutex_t *mutex)
226{
227#ifdef DEBUG_GXX_WRAPPERS
228   printk( "gxx_wrappers: unlock mutex=%X\n", *mutex );
229#endif
230  return (rtems_semaphore_release( (rtems_id)*mutex ) ==  RTEMS_SUCCESSFUL) ? 0 :-1;
231}
[f49a82f3]232
[6d1e301a]233void rtems_gxx_recursive_mutex_init(__gthread_recursive_mutex_t *mutex)
[f49a82f3]234{
235  rtems_gxx_mutex_init(mutex);
236}
237
238int rtems_gxx_recursive_mutex_lock(__gthread_recursive_mutex_t *mutex)
239{
240  return rtems_gxx_mutex_lock(mutex);
241}
242
243int rtems_gxx_recursive_mutex_trylock(__gthread_recursive_mutex_t *mutex)
244{
245  return rtems_gxx_mutex_trylock(mutex);
246}
247
248int rtems_gxx_recursive_mutex_unlock(__gthread_recursive_mutex_t *mutex)
249{
250  return rtems_gxx_mutex_unlock(mutex);
251}
252
253#endif /* __GNUC__ */
Note: See TracBrowser for help on using the repository browser.