1169689Skan/* Threads compatibility routines for libgcc2 and libobjc.
2169689Skan   Compile this one with gcc.
3169689Skan   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
4169689Skan
5169689SkanThis file is part of GCC.
6169689Skan
7169689SkanGCC is free software; you can redistribute it and/or modify it under
8169689Skanthe terms of the GNU General Public License as published by the Free
9169689SkanSoftware Foundation; either version 2, or (at your option) any later
10169689Skanversion.
11169689Skan
12169689SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY
13169689SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or
14169689SkanFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15169689Skanfor more details.
16169689Skan
17169689SkanYou should have received a copy of the GNU General Public License
18169689Skanalong with GCC; see the file COPYING.  If not, write to the Free
19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169689Skan02110-1301, USA.  */
21169689Skan
22169689Skan/* As a special exception, if you link this library with other files,
23169689Skan   some of which are compiled with GCC, to produce an executable,
24169689Skan   this library does not by itself cause the resulting executable
25169689Skan   to be covered by the GNU General Public License.
26169689Skan   This exception does not however invalidate any other reasons why
27169689Skan   the executable file might be covered by the GNU General Public License.  */
28169689Skan
29169689Skan
30169689Skan/* TPF needs its own version of gthr-*.h because TPF always links to
31169689Skan   the thread library.  However, for performance reasons we still do not
32169689Skan   want to issue thread api calls unless a check is made to see that we
33169689Skan   are running as a thread.  */
34169689Skan
35169689Skan#ifndef GCC_GTHR_TPF_H
36169689Skan#define GCC_GTHR_TPF_H
37169689Skan
38169689Skan/* POSIX threads specific definitions.
39169689Skan   Easy, since the interface is just one-to-one mapping.  */
40169689Skan
41169689Skan#define __GTHREADS 1
42169689Skan
43169689Skan/* Some implementations of <pthread.h> require this to be defined.  */
44169689Skan#ifndef _REENTRANT
45169689Skan#define _REENTRANT 1
46169689Skan#endif
47169689Skan
48169689Skan#include <pthread.h>
49169689Skan#include <unistd.h>
50169689Skan
51169689Skantypedef pthread_key_t __gthread_key_t;
52169689Skantypedef pthread_once_t __gthread_once_t;
53169689Skantypedef pthread_mutex_t __gthread_mutex_t;
54169689Skantypedef pthread_mutex_t __gthread_recursive_mutex_t;
55169689Skan
56169689Skan#if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
57169689Skan#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
58169689Skan#elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
59169689Skan#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
60169689Skan#endif
61169689Skan
62169689Skan#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
63169689Skan#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
64169689Skan#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
65169689Skan
66169689Skan#define NOTATHREAD   00
67169689Skan#define ECBBASEPTR (unsigned long int) *(unsigned int *)0x00000514u
68169689Skan#define ECBPG2PTR  ECBBASEPTR + 0x1000
69169689Skan#define CE2THRCPTR *((unsigned char *)(ECBPG2PTR + 16))
70169689Skan#define __tpf_pthread_active() (CE2THRCPTR != NOTATHREAD)
71169689Skan
72169689Skan#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
73169689Skan# define __gthrw(name) \
74169689Skan  static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name)));
75169689Skan# define __gthrw_(name) __gthrw_ ## name
76169689Skan#else
77169689Skan# define __gthrw(name)
78169689Skan# define __gthrw_(name) name
79169689Skan#endif
80169689Skan
81169689Skan__gthrw(pthread_once)
82169689Skan__gthrw(pthread_key_create)
83169689Skan__gthrw(pthread_key_delete)
84169689Skan__gthrw(pthread_getspecific)
85169689Skan__gthrw(pthread_setspecific)
86169689Skan__gthrw(pthread_create)
87169689Skan
88169689Skan__gthrw(pthread_mutex_lock)
89169689Skan__gthrw(pthread_mutex_trylock)
90169689Skan__gthrw(pthread_mutex_unlock)
91169689Skan__gthrw(pthread_mutexattr_init)
92169689Skan__gthrw(pthread_mutexattr_settype)
93169689Skan__gthrw(pthread_mutexattr_destroy)
94169689Skan__gthrw(pthread_mutex_init)
95169689Skan
96169689Skanstatic inline int
97169689Skan__gthread_active_p (void)
98169689Skan{
99169689Skan  return 1;
100169689Skan}
101169689Skan
102169689Skanstatic inline int
103169689Skan__gthread_once (__gthread_once_t *once, void (*func) (void))
104169689Skan{
105169689Skan  if (__tpf_pthread_active ())
106169689Skan    return __gthrw_(pthread_once) (once, func);
107169689Skan  else
108169689Skan    return -1;
109169689Skan}
110169689Skan
111169689Skanstatic inline int
112169689Skan__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
113169689Skan{
114169689Skan  if (__tpf_pthread_active ())
115169689Skan    return __gthrw_(pthread_key_create) (key, dtor);
116169689Skan  else
117169689Skan    return -1;
118169689Skan}
119169689Skan
120169689Skanstatic inline int
121169689Skan__gthread_key_delete (__gthread_key_t key)
122169689Skan{
123169689Skan  if (__tpf_pthread_active ())
124169689Skan    return __gthrw_(pthread_key_delete) (key);
125169689Skan  else
126169689Skan    return -1;
127169689Skan}
128169689Skan
129169689Skanstatic inline void *
130169689Skan__gthread_getspecific (__gthread_key_t key)
131169689Skan{
132169689Skan  if (__tpf_pthread_active ())
133169689Skan    return __gthrw_(pthread_getspecific) (key);
134169689Skan  else
135169689Skan    return NULL;
136169689Skan}
137169689Skan
138169689Skanstatic inline int
139169689Skan__gthread_setspecific (__gthread_key_t key, const void *ptr)
140169689Skan{
141169689Skan  if (__tpf_pthread_active ())
142169689Skan    return __gthrw_(pthread_setspecific) (key, ptr);
143169689Skan  else
144169689Skan    return -1;
145169689Skan}
146169689Skan
147169689Skanstatic inline int
148169689Skan__gthread_mutex_lock (__gthread_mutex_t *mutex)
149169689Skan{
150169689Skan  if (__tpf_pthread_active ())
151169689Skan    return __gthrw_(pthread_mutex_lock) (mutex);
152169689Skan  else
153169689Skan    return 0;
154169689Skan}
155169689Skan
156169689Skanstatic inline int
157169689Skan__gthread_mutex_trylock (__gthread_mutex_t *mutex)
158169689Skan{
159169689Skan  if (__tpf_pthread_active ())
160169689Skan    return __gthrw_(pthread_mutex_trylock) (mutex);
161169689Skan  else
162169689Skan    return 0;
163169689Skan}
164169689Skan
165169689Skanstatic inline int
166169689Skan__gthread_mutex_unlock (__gthread_mutex_t *mutex)
167169689Skan{
168169689Skan  if (__tpf_pthread_active ())
169169689Skan    return __gthrw_(pthread_mutex_unlock) (mutex);
170169689Skan  else
171169689Skan    return 0;
172169689Skan}
173169689Skan
174169689Skanstatic inline int
175169689Skan__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
176169689Skan{
177169689Skan  if (__tpf_pthread_active ())
178169689Skan    return __gthread_mutex_lock (mutex);
179169689Skan  else
180169689Skan    return 0;
181169689Skan}
182169689Skan
183169689Skanstatic inline int
184169689Skan__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
185169689Skan{
186169689Skan  if (__tpf_pthread_active ())
187169689Skan    return __gthread_mutex_trylock (mutex);
188169689Skan  else
189169689Skan    return 0;
190169689Skan}
191169689Skan
192169689Skanstatic inline int
193169689Skan__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
194169689Skan{
195169689Skan  if (__tpf_pthread_active ())
196169689Skan    return __gthread_mutex_unlock (mutex);
197169689Skan  else
198169689Skan    return 0;
199169689Skan}
200169689Skan
201169689Skanstatic inline int
202169689Skan__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
203169689Skan{
204169689Skan  if (__tpf_pthread_active ())
205169689Skan    {
206169689Skan      pthread_mutexattr_t attr;
207169689Skan      int r;
208169689Skan
209169689Skan      r = __gthrw_(pthread_mutexattr_init) (&attr);
210169689Skan      if (!r)
211169689Skan	r = __gthrw_(pthread_mutexattr_settype) (&attr, PTHREAD_MUTEX_RECURSIVE);
212169689Skan      if (!r)
213169689Skan	r = __gthrw_(pthread_mutex_init) (mutex, &attr);
214169689Skan      if (!r)
215169689Skan	r = __gthrw_(pthread_mutexattr_destroy) (&attr);
216169689Skan      return r;
217169689Skan    }
218169689Skan  return 0;
219169689Skan}
220169689Skan
221169689Skan
222169689Skan#endif /* ! GCC_GTHR_TPF_H */
223