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

4.115
Last change on this file since a5385b1 was a5385b1, checked in by Christian Mauderer <Christian.Mauderer@…>, on 03/20/14 at 08:22:00

score: Unify pthread and gxx_wrapper once and move to score.

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