# gthr-tpf.h

    00001 /* Threads compatibility routines for libgcc2 and libobjc.
    00002    Compile this one with gcc.
    00003    Copyright (C) 2004, 2005 Free Software Foundation, Inc.
    00004
    00005 This file is part of GCC.
    00006
    00007 GCC is free software; you can redistribute it and/or modify it under
    00008 the terms of the GNU General Public License as published by the Free
    00009 Software Foundation; either version 2, or (at your option) any later
    00010 version.
    00011
    00012 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
    00013 WARRANTY; without even the implied warranty of MERCHANTABILITY or
    00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    00015 for more details.
    00016
    00017 You should have received a copy of the GNU General Public License
    00018 along with GCC; see the file COPYING.  If not, write to the Free
    00019 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
    00020 02110-1301, USA.  */
    00021
    00022 /* As a special exception, if you link this library with other files,
    00023    some of which are compiled with GCC, to produce an executable,
    00024    this library does not by itself cause the resulting executable
    00025    to be covered by the GNU General Public License.
    00026    This exception does not however invalidate any other reasons why
    00027    the executable file might be covered by the GNU General Public License.  */
    00028
    00029
    00030 /* TPF needs its own version of gthr-*.h because TPF always links to
    00031    the thread library.  However, for performance reasons we still do not
    00032    want to issue thread api calls unless a check is made to see that we
    00033    are running as a thread.  */
    00034
    00035 #ifndef _GLIBCXX_GCC_GTHR_TPF_H
    00036 #define _GLIBCXX_GCC_GTHR_TPF_H
    00037
    00038 /* POSIX threads specific definitions.
    00039    Easy, since the interface is just one-to-one mapping.  */
    00040
    00041 #define __GTHREADS 1
    00042
    00043 /* Some implementations of <pthread.h> require this to be defined.  */
    00044 #ifndef _REENTRANT
    00045 #define _REENTRANT 1
    00046 #endif
    00047
    00048 #include <pthread.h>
    00049 #include <unistd.h>
    00050
    00051 typedef pthread_key_t __gthread_key_t;
    00052 typedef pthread_once_t __gthread_once_t;
    00053 typedef pthread_mutex_t __gthread_mutex_t;
    00054 typedef pthread_mutex_t __gthread_recursive_mutex_t;
    00055
    00056 #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
    00057 #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
    00058 #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
    00059 #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
    00060 #endif
    00061
    00062 #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
    00063 #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
    00064 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
    00065
    00066 #define NOTATHREAD   00
    00067 #define ECBBASEPTR (unsigned long int) *(unsigned int *)0x00000514u
    00068 #define ECBPG2PTR  ECBBASEPTR + 0x1000
    00069 #define CE2THRCPTR *((unsigned char *)(ECBPG2PTR + 16))
    00070 #define __tpf_pthread_active() (CE2THRCPTR != NOTATHREAD)
    00071
    00072 #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
    00073 # define __gthrw(name) \
    00074   static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name)));
    00075 # define __gthrw_(name) __gthrw_ ## name
    00076 #else
    00077 # define __gthrw(name)
    00078 # define __gthrw_(name) name
    00079 #endif
    00080
    00081 __gthrw(pthread_once)
    00082 __gthrw(pthread_key_create)
    00083 __gthrw(pthread_key_delete)
    00084 __gthrw(pthread_getspecific)
    00085 __gthrw(pthread_setspecific)
    00086 __gthrw(pthread_create)
    00087
    00088 __gthrw(pthread_mutex_lock)
    00089 __gthrw(pthread_mutex_trylock)
    00090 __gthrw(pthread_mutex_unlock)
    00091 __gthrw(pthread_mutexattr_init)
    00092 __gthrw(pthread_mutexattr_settype)
    00093 __gthrw(pthread_mutexattr_destroy)
    00094 __gthrw(pthread_mutex_init)
    00095
    00096 static inline int
    00097 __gthread_active_p (void)
    00098 {
    00099   return 1;
    00100 }
    00101
    00102 static inline int
    00103 __gthread_once (__gthread_once_t *once, void (*func) (void))
    00104 {
    00105   if (__tpf_pthread_active ())
    00106     return __gthrw_(pthread_once) (once, func);
    00107   else
    00108     return -1;
    00109 }
    00110
    00111 static inline int
    00112 __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
    00113 {
    00114   if (__tpf_pthread_active ())
    00115     return __gthrw_(pthread_key_create) (key, dtor);
    00116   else
    00117     return -1;
    00118 }
    00119
    00120 static inline int
    00121 __gthread_key_delete (__gthread_key_t key)
    00122 {
    00123   if (__tpf_pthread_active ())
    00124     return __gthrw_(pthread_key_delete) (key);
    00125   else
    00126     return -1;
    00127 }
    00128
    00129 static inline void *
    00130 __gthread_getspecific (__gthread_key_t key)
    00131 {
    00132   if (__tpf_pthread_active ())
    00133     return __gthrw_(pthread_getspecific) (key);
    00134   else
    00135     return NULL;
    00136 }
    00137
    00138 static inline int
    00139 __gthread_setspecific (__gthread_key_t key, const void *ptr)
    00140 {
    00141   if (__tpf_pthread_active ())
    00142     return __gthrw_(pthread_setspecific) (key, ptr);
    00143   else
    00144     return -1;
    00145 }
    00146
    00147 static inline int
    00148 __gthread_mutex_lock (__gthread_mutex_t *mutex)
    00149 {
    00150   if (__tpf_pthread_active ())
    00151     return __gthrw_(pthread_mutex_lock) (mutex);
    00152   else
    00153     return 0;
    00154 }
    00155
    00156 static inline int
    00157 __gthread_mutex_trylock (__gthread_mutex_t *mutex)
    00158 {
    00159   if (__tpf_pthread_active ())
    00160     return __gthrw_(pthread_mutex_trylock) (mutex);
    00161   else
    00162     return 0;
    00163 }
    00164
    00165 static inline int
    00166 __gthread_mutex_unlock (__gthread_mutex_t *mutex)
    00167 {
    00168   if (__tpf_pthread_active ())
    00169     return __gthrw_(pthread_mutex_unlock) (mutex);
    00170   else
    00171     return 0;
    00172 }
    00173
    00174 static inline int
    00175 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
    00176 {
    00177   if (__tpf_pthread_active ())
    00178     return __gthread_mutex_lock (mutex);
    00179   else
    00180     return 0;
    00181 }
    00182
    00183 static inline int
    00184 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
    00185 {
    00186   if (__tpf_pthread_active ())
    00187     return __gthread_mutex_trylock (mutex);
    00188   else
    00189     return 0;
    00190 }
    00191
    00192 static inline int
    00193 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
    00194 {
    00195   if (__tpf_pthread_active ())
    00196     return __gthread_mutex_unlock (mutex);
    00197   else
    00198     return 0;
    00199 }
    00200
    00201 static inline int
    00202 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
    00203 {
    00204   if (__tpf_pthread_active ())
    00205     {
    00206       pthread_mutexattr_t attr;
    00207       int r;
    00208
    00209       r = __gthrw_(pthread_mutexattr_init) (&attr);
    00210       if (!r)
    00211     r = __gthrw_(pthread_mutexattr_settype) (&attr, PTHREAD_MUTEX_RECURSIVE);
    00212       if (!r)
    00213     r = __gthrw_(pthread_mutex_init) (mutex, &attr);
    00214       if (!r)
    00215     r = __gthrw_(pthread_mutexattr_destroy) (&attr);
    00216       return r;
    00217     }
    00218   return 0;
    00219 }
    00220
    00221
    00222 #endif /* ! _GLIBCXX_GCC_GTHR_TPF_H */