gthr-vxworks.h revision 117395
1/* Threads compatibility routines for libgcc2 and libobjc for VxWorks.  */
2/* Compile this one with gcc.  */
3/* Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
4   Contributed by Mike Stump <mrs@wrs.com>.
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING.  If not, write to the Free
20Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2102111-1307, USA.  */
22
23/* As a special exception, if you link this library with other files,
24   some of which are compiled with GCC, to produce an executable,
25   this library does not by itself cause the resulting executable
26   to be covered by the GNU General Public License.
27   This exception does not however invalidate any other reasons why
28   the executable file might be covered by the GNU General Public License.  */
29
30#ifndef GCC_GTHR_VXWORKS_H
31#define GCC_GTHR_VXWORKS_H
32
33#ifdef _LIBOBJC
34
35/* Thread local storage for a single thread */
36static void *thread_local_storage = NULL;
37
38/* Backend initialization functions */
39
40/* Initialize the threads subsystem.  */
41int
42__gthread_objc_init_thread_system (void)
43{
44  /* No thread support available */
45  return -1;
46}
47
48/* Close the threads subsystem.  */
49int
50__gthread_objc_close_thread_system (void)
51{
52  /* No thread support available */
53  return -1;
54}
55
56/* Backend thread functions */
57
58/* Create a new thread of execution.  */
59objc_thread_t
60__gthread_objc_thread_detach (void (*func)(void *arg), void *arg)
61{
62  /* No thread support available */
63  return NULL;
64}
65
66/* Set the current thread's priority.  */
67int
68__gthread_objc_thread_set_priority (int priority)
69{
70  /* No thread support available */
71  return -1;
72}
73
74/* Return the current thread's priority.  */
75int
76__gthread_objc_thread_get_priority (void)
77{
78  return OBJC_THREAD_INTERACTIVE_PRIORITY;
79}
80
81/* Yield our process time to another thread.  */
82void
83__gthread_objc_thread_yield (void)
84{
85  return;
86}
87
88/* Terminate the current thread.  */
89int
90__gthread_objc_thread_exit (void)
91{
92  /* No thread support available */
93  /* Should we really exit the program */
94  /* exit (&__objc_thread_exit_status); */
95  return -1;
96}
97
98/* Returns an integer value which uniquely describes a thread.  */
99objc_thread_t
100__gthread_objc_thread_id (void)
101{
102  /* No thread support, use 1.  */
103  return (objc_thread_t) 1;
104}
105
106/* Sets the thread's local storage pointer.  */
107int
108__gthread_objc_thread_set_data (void *value)
109{
110  thread_local_storage = value;
111  return 0;
112}
113
114/* Returns the thread's local storage pointer.  */
115void *
116__gthread_objc_thread_get_data (void)
117{
118  return thread_local_storage;
119}
120
121/* Backend mutex functions */
122
123/* Allocate a mutex.  */
124int
125__gthread_objc_mutex_allocate (objc_mutex_t mutex)
126{
127  return 0;
128}
129
130/* Deallocate a mutex.  */
131int
132__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
133{
134  return 0;
135}
136
137/* Grab a lock on a mutex.  */
138int
139__gthread_objc_mutex_lock (objc_mutex_t mutex)
140{
141  /* There can only be one thread, so we always get the lock */
142  return 0;
143}
144
145/* Try to grab a lock on a mutex.  */
146int
147__gthread_objc_mutex_trylock (objc_mutex_t mutex)
148{
149  /* There can only be one thread, so we always get the lock */
150  return 0;
151}
152
153/* Unlock the mutex */
154int
155__gthread_objc_mutex_unlock (objc_mutex_t mutex)
156{
157  return 0;
158}
159
160/* Backend condition mutex functions */
161
162/* Allocate a condition.  */
163int
164__gthread_objc_condition_allocate (objc_condition_t condition)
165{
166  return 0;
167}
168
169/* Deallocate a condition.  */
170int
171__gthread_objc_condition_deallocate (objc_condition_t condition)
172{
173  return 0;
174}
175
176/* Wait on the condition */
177int
178__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
179{
180  return 0;
181}
182
183/* Wake up all threads waiting on this condition.  */
184int
185__gthread_objc_condition_broadcast (objc_condition_t condition)
186{
187  return 0;
188}
189
190/* Wake up one thread waiting on this condition.  */
191int
192__gthread_objc_condition_signal (objc_condition_t condition)
193{
194  return 0;
195}
196
197#else /* _LIBOBJC */
198
199/* POSIX threads specific definitions.
200   Easy, since the interface is just one-to-one mapping.  */
201
202#define __GTHREADS 1
203
204#include <vxWorks.h>
205#include <semLib.h>
206/* typedef void *SEM_ID; */
207
208typedef int __gthread_key_t;
209typedef char __gthread_once_t;
210typedef SEM_ID __gthread_mutex_t;
211
212#define __GTHREAD_MUTEX_INIT 0
213#define __GTHREAD_ONCE_INIT 0
214
215#ifndef REG_SAVED_REG
216static inline int
217__gthread_once (__gthread_once_t *once, void (*func) (void))
218{
219  (*func)();
220  return 0;
221}
222
223extern __gthread_key_t eh_context_key;
224
225/* This is not the right way to do it, but the semantic of pthreads
226   don't map well enough onto VxWorks.  */
227
228static void
229__ehdtor (void *pTcb)
230{
231  int tid = (int) pTcb;
232  void *p = (void *) taskVarGet (tid, &eh_context_key);
233  if (p != (void *) -1)
234    {
235      if (p)
236	free (p);
237      taskVarSet (tid, &eh_context_key, 0);
238    }
239}
240
241/* This only works for the code in libgcc2.c.  */
242
243static inline int
244__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
245{
246  *key = 0;
247
248  /* Do this first so that the task variables are visible during the
249     running of the delete hook.  */
250
251  taskVarInit ();
252
253  /* We don't have a way to track dtor here, so instead, we
254     register a generic routine that can cleanup any task.  */
255
256  taskDeleteHookAdd (__ehdtor);
257
258  return 0;
259}
260
261#define __gthread_setspecific(key, ptr) \
262  (key = (int) ptr, 0)
263
264static inline int
265__gthread_key_dtor (__gthread_key_t key, void *ptr)
266{
267  /* Just reset the key value to zero.  */
268  if (ptr)
269    return __gthread_setspecific (key, 0);
270  else
271    return 0;
272}
273
274#define __gthread_key_delete(key) \
275  taskVarDelete (taskIdSelf (), &key)
276
277#define __gthread_getspecific(key)			\
278     ((key == 0)					\
279      ? ((taskVarAdd (taskIdSelf (), &key) != OK)	\
280	 ? (__terminate (), (void *) 0)			\
281	 : (void *) 0)					\
282      : (void *) key)
283#endif
284
285static inline int
286__gthread_mutex_lock (__gthread_mutex_t *mutex)
287{
288  if (*mutex == 0)
289    *mutex = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);
290  return semTake (*mutex, WAIT_FOREVER);
291}
292
293static inline int
294__gthread_mutex_trylock (__gthread_mutex_t *mutex)
295{
296  if (*mutex == 0)
297    *mutex = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);
298  return semTake (*mutex, NO_WAIT);
299}
300
301static inline int
302__gthread_mutex_unlock (__gthread_mutex_t *mutex)
303{
304  /* We could return the */
305  return semGive (*mutex);
306}
307
308#endif /* _LIBOBJC */
309
310#endif /* ! GCC_GTHR_VXWORKS_H */
311