source: rtems/c/src/lib/libc/gxx_wrappers.c @ 23e3ce64

4.104.114.84.95
Last change on this file since 23e3ce64 was df49c60, checked in by Joel Sherrill <joel.sherrill@…>, on 06/12/00 at 15:00:15

Merged from 4.5.0-beta3a

  • Property mode set to 100644
File size: 5.6 KB
Line 
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 *
16 *
17 */
18
19/* We might not need, defined just in case */
20#define  __RTEMS_INSIDE__  1
21
22
23#include <stdlib.h>
24#include <stdio.h>
25
26#include <rtems.h>
27#include <rtems/system.h>
28#include <rtems/rtems/tasks.h>
29
30/*
31 * These typedefs should match with the ones defined in the file
32 * gcc/gthr-rtems.h in the gcc distribution.
33 */
34typedef void *__gthread_key_t;
35typedef int   __gthread_once_t;
36typedef void *__gthread_mutex_t;
37
38
39/* uncomment this if you need to debug this interface */
40
41/*
42#define DEBUG_GXX_WRAPPERS 1
43*/
44
45
46/* prototype for the terminate() */
47extern void __terminate( void );
48
49
50#ifdef DEBUG_GXX_WRAPPERS
51/* local function to return the ID of the calling thread */
52static rtems_id get_tid( void )
53{
54   rtems_id id = 0;
55   rtems_task_ident( RTEMS_SELF, 0, &id );
56   return id;
57}
58#endif
59
60
61int rtems_gxx_once(__gthread_once_t *once, void (*func) ())
62{
63#ifdef DEBUG_GXX_WRAPPERS
64   printk( "gxx_wrappers: once=%x, func=%x\n", *once, func );
65#endif
66   if( *once == 0 )
67   {
68      /*
69       * NOTE: could not use the call to disable "preemption", it causes
70       * one exception. Somebody might want to investiage it further
71       * sometime later.
72       */
73      _Thread_Disable_dispatch();
74      *once = 1;
75      (*func)();
76      _Thread_Enable_dispatch();
77   }
78   return 0;
79}
80
81
82int rtems_gxx_key_create (__gthread_key_t *key, void (*dtor) (void *))
83{
84  /* Ok, this can be a bit tricky. We are going to return a "key" as a
85   * pointer to the buffer that will hold the value of the key itself.
86   * We have to to this, becuase the others functions on this interface
87   * deal with the value of the key, as used with the POSIX API.
88   */
89   /* Do not pull your hair, trust me this works. :-) */
90  __gthread_key_t *new_key = ( __gthread_key_t * )malloc( sizeof( __gthread_key_t ) );
91  *key = ( __gthread_key_t )new_key;
92  *new_key = NULL;
93
94#ifdef DEBUG_GXX_WRAPPERS
95  printk( "gxx_wrappers: create key=%x, dtor=%x, new_key=%x\n", key, dtor, new_key );
96#endif
97  /* register with RTEMS the buffer that will hold the key values */
98  if( rtems_task_variable_add( RTEMS_SELF, (void **)new_key, NULL ) == 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   *(void **)key = 0;
109   return 0;
110}
111
112int rtems_gxx_key_delete (__gthread_key_t key)
113{
114#ifdef DEBUG_GXX_WRAPPERS
115  printk( "gxx_wrappers: delete key=%x\n", key );
116#endif
117  /* register with RTEMS the buffer that will hold the key values */
118  if( rtems_task_variable_delete( RTEMS_SELF, (void **)key ) == RTEMS_SUCCESSFUL )
119  {
120     if( key ) free( (void *)key );
121     return 0;
122  }
123  return 0;
124}
125
126
127void *rtems_gxx_getspecific(__gthread_key_t key)
128{
129  void *p= 0;
130
131  /* register with RTEMS the buffer that will hold the key values */
132  if( rtems_task_variable_get( RTEMS_SELF, (void **)key, &p ) == RTEMS_SUCCESSFUL )
133  {
134    /* We do not have to do this, but what the heck ! */
135     p= *( void **)key;
136  }
137  else
138  {
139    /* fisrt time, always set to zero, it is unknown the value that the others
140     * threads are using at the moment of this call
141     */
142    if( rtems_task_variable_add( RTEMS_SELF, (void **)key, NULL ) != RTEMS_SUCCESSFUL )
143    {
144       __terminate ();
145    }
146    *( void ** )key = (void *)0;
147  }
148
149#ifdef DEBUG_GXX_WRAPPERS
150   printk( "gxx_wrappers: getspecific key=%x, ptr=%x, id=%x\n", key, p, get_tid() );
151#endif
152   return p;
153}
154
155
156int rtems_gxx_setspecific(__gthread_key_t key, const void *ptr)
157{
158#ifdef DEBUG_GXX_WRAPPERS
159  printk( "gxx_wrappers: setspecific key=%x, ptr=%x, id=%x\n", key, ptr, get_tid() );
160#endif
161  /* register with RTEMS the buffer that will hold the key values */
162  if( rtems_task_variable_add( RTEMS_SELF, (void **)key, NULL ) == RTEMS_SUCCESSFUL )
163  {
164    /* now let's set the proper value */
165    *( void ** )key = (void *)ptr;
166     return 0;
167  }
168  return -1;
169}
170
171
172/*
173 * MUTEX support
174 */
175void rtems_gxx_mutex_init (__gthread_mutex_t *mutex)
176{
177#ifdef DEBUG_GXX_WRAPPERS
178  printk( "gxx_wrappers: mutex init =%X\n", *mutex );
179#endif
180  if( rtems_semaphore_create( rtems_build_name ('G', 'C', 'C', '2'),
181                              1,
182                             RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE
183                             |RTEMS_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL,
184                             0,
185                             (rtems_id *)mutex ) != RTEMS_SUCCESSFUL )
186  {
187      __terminate ();
188  }
189#ifdef DEBUG_GXX_WRAPPERS
190  printk( "gxx_wrappers: mutex init complete =%X\n", *mutex );
191#endif
192}
193
194int rtems_gxx_mutex_lock (__gthread_mutex_t *mutex)
195{
196#ifdef DEBUG_GXX_WRAPPERS
197  printk( "gxx_wrappers: lock mutex=%X\n", *mutex );
198#endif
199  return ( rtems_semaphore_obtain( (rtems_id)*mutex,
200            RTEMS_WAIT, RTEMS_NO_TIMEOUT ) ==  RTEMS_SUCCESSFUL) ? 0 : -1;
201}
202
203int rtems_gxx_mutex_trylock (__gthread_mutex_t *mutex)
204{
205#ifdef DEBUG_GXX_WRAPPERS
206  printk( "gxx_wrappers: trylock mutex=%X\n", *mutex );
207#endif
208  return (rtems_semaphore_obtain ((rtems_id)*mutex,
209               RTEMS_NO_WAIT, 0) == RTEMS_SUCCESSFUL) ? 0 : -1;
210}
211
212int rtems_gxx_mutex_unlock (__gthread_mutex_t *mutex)
213{
214#ifdef DEBUG_GXX_WRAPPERS
215   printk( "gxx_wrappers: unlock mutex=%X\n", *mutex );
216#endif
217  return (rtems_semaphore_release( (rtems_id)*mutex ) ==  RTEMS_SUCCESSFUL) ? 0 :-1;
218}
219
Note: See TracBrowser for help on using the repository browser.