Home | History | Annotate | Download | only in bits
      1 /* Threads compatibility routines for libgcc2 and libobjc.
      2    Compile this one with gcc.
      3    Copyright (C) 2004, 2005, 2008, 2009 Free Software Foundation, Inc.
      4 
      5 This file is part of GCC.
      6 
      7 GCC is free software; you can redistribute it and/or modify it under
      8 the terms of the GNU General Public License as published by the Free
      9 Software Foundation; either version 3, or (at your option) any later
     10 version.
     11 
     12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15 for more details.
     16 
     17 Under Section 7 of GPL version 3, you are granted additional
     18 permissions described in the GCC Runtime Library Exception, version
     19 3.1, as published by the Free Software Foundation.
     20 
     21 You should have received a copy of the GNU General Public License and
     22 a copy of the GCC Runtime Library Exception along with this program;
     23 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     24 <http://www.gnu.org/licenses/>.  */
     25 
     26 /* TPF needs its own version of gthr-*.h because TPF always links to
     27    the thread library.  However, for performance reasons we still do not
     28    want to issue thread api calls unless a check is made to see that we
     29    are running as a thread.  */
     30 
     31 #ifndef _GLIBCXX_GCC_GTHR_TPF_H
     32 #define _GLIBCXX_GCC_GTHR_TPF_H
     33 
     34 /* POSIX threads specific definitions.
     35    Easy, since the interface is just one-to-one mapping.  */
     36 
     37 #define __GTHREADS 1
     38 
     39 /* Some implementations of <pthread.h> require this to be defined.  */
     40 #ifndef _REENTRANT
     41 #define _REENTRANT 1
     42 #endif
     43 
     44 #include <pthread.h>
     45 #include <unistd.h>
     46 
     47 typedef pthread_key_t __gthread_key_t;
     48 typedef pthread_once_t __gthread_once_t;
     49 typedef pthread_mutex_t __gthread_mutex_t;
     50 typedef pthread_mutex_t __gthread_recursive_mutex_t;
     51 
     52 #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
     53 #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
     54 #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
     55 #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
     56 #endif
     57 
     58 #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
     59 #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
     60 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
     61 
     62 #define NOTATHREAD   00
     63 #define ECBBASEPTR (unsigned long int) *(unsigned int *)0x00000514u
     64 #define ECBPG2PTR  ECBBASEPTR + 0x1000
     65 #define CE2THRCPTR *((unsigned char *)(ECBPG2PTR + 16))
     66 #define __tpf_pthread_active() (CE2THRCPTR != NOTATHREAD)
     67 
     68 #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
     69 # define __gthrw(name) \
     70   static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name)));
     71 # define __gthrw_(name) __gthrw_ ## name
     72 #else
     73 # define __gthrw(name)
     74 # define __gthrw_(name) name
     75 #endif
     76 
     77 __gthrw(pthread_once)
     78 __gthrw(pthread_key_create)
     79 __gthrw(pthread_key_delete)
     80 __gthrw(pthread_getspecific)
     81 __gthrw(pthread_setspecific)
     82 __gthrw(pthread_create)
     83 
     84 __gthrw(pthread_mutex_lock)
     85 __gthrw(pthread_mutex_trylock)
     86 __gthrw(pthread_mutex_unlock)
     87 __gthrw(pthread_mutexattr_init)
     88 __gthrw(pthread_mutexattr_settype)
     89 __gthrw(pthread_mutexattr_destroy)
     90 __gthrw(pthread_mutex_init)
     91 __gthrw(pthread_mutex_destroy)
     92 
     93 static inline int
     94 __gthread_active_p (void)
     95 {
     96   return 1;
     97 }
     98 
     99 static inline int
    100 __gthread_once (__gthread_once_t *__once, void (*__func) (void))
    101 {
    102   if (__tpf_pthread_active ())
    103     return __gthrw_(pthread_once) (__once, __func);
    104   else
    105     return -1;
    106 }
    107 
    108 static inline int
    109 __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
    110 {
    111   if (__tpf_pthread_active ())
    112     return __gthrw_(pthread_key_create) (__key, __dtor);
    113   else
    114     return -1;
    115 }
    116 
    117 static inline int
    118 __gthread_key_delete (__gthread_key_t __key)
    119 {
    120   if (__tpf_pthread_active ())
    121     return __gthrw_(pthread_key_delete) (__key);
    122   else
    123     return -1;
    124 }
    125 
    126 static inline void *
    127 __gthread_getspecific (__gthread_key_t __key)
    128 {
    129   if (__tpf_pthread_active ())
    130     return __gthrw_(pthread_getspecific) (__key);
    131   else
    132     return NULL;
    133 }
    134 
    135 static inline int
    136 __gthread_setspecific (__gthread_key_t __key, const void *__ptr)
    137 {
    138   if (__tpf_pthread_active ())
    139     return __gthrw_(pthread_setspecific) (__key, __ptr);
    140   else
    141     return -1;
    142 }
    143 
    144 static inline int
    145 __gthread_mutex_destroy (__gthread_mutex_t *__mutex)
    146 {
    147   if (__tpf_pthread_active ())
    148     return __gthrw_(pthread_mutex_destroy) (__mutex);
    149   else
    150     return 0;
    151 }
    152 
    153 static inline int
    154 __gthread_mutex_lock (__gthread_mutex_t *__mutex)
    155 {
    156   if (__tpf_pthread_active ())
    157     return __gthrw_(pthread_mutex_lock) (__mutex);
    158   else
    159     return 0;
    160 }
    161 
    162 static inline int
    163 __gthread_mutex_trylock (__gthread_mutex_t *__mutex)
    164 {
    165   if (__tpf_pthread_active ())
    166     return __gthrw_(pthread_mutex_trylock) (__mutex);
    167   else
    168     return 0;
    169 }
    170 
    171 static inline int
    172 __gthread_mutex_unlock (__gthread_mutex_t *__mutex)
    173 {
    174   if (__tpf_pthread_active ())
    175     return __gthrw_(pthread_mutex_unlock) (__mutex);
    176   else
    177     return 0;
    178 }
    179 
    180 static inline int
    181 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
    182 {
    183   if (__tpf_pthread_active ())
    184     return __gthread_mutex_lock (__mutex);
    185   else
    186     return 0;
    187 }
    188 
    189 static inline int
    190 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
    191 {
    192   if (__tpf_pthread_active ())
    193     return __gthread_mutex_trylock (__mutex);
    194   else
    195     return 0;
    196 }
    197 
    198 static inline int
    199 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
    200 {
    201   if (__tpf_pthread_active ())
    202     return __gthread_mutex_unlock (__mutex);
    203   else
    204     return 0;
    205 }
    206 
    207 static inline int
    208 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
    209 {
    210   if (__tpf_pthread_active ())
    211     {
    212       pthread_mutexattr_t __attr;
    213       int __r;
    214 
    215       __r = __gthrw_(pthread_mutexattr_init) (&__attr);
    216       if (!__r)
    217 	__r = __gthrw_(pthread_mutexattr_settype) (&__attr,
    218 						   PTHREAD_MUTEX_RECURSIVE);
    219       if (!__r)
    220 	__r = __gthrw_(pthread_mutex_init) (__mutex, &__attr);
    221       if (!__r)
    222 	__r = __gthrw_(pthread_mutexattr_destroy) (&__attr);
    223       return __r;
    224     }
    225   return 0;
    226 }
    227 
    228 
    229 #endif /* ! _GLIBCXX_GCC_GTHR_TPF_H */
    230