1/* MIPS SDE threads compatibility routines for libgcc2 and libobjc. */ 2/* Compile this one with gcc. */ 3/* Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc. 4 Contributed by Nigel Stephens <nigel@mips.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 3, 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 18Under Section 7 of GPL version 3, you are granted additional 19permissions described in the GCC Runtime Library Exception, version 203.1, as published by the Free Software Foundation. 21 22You should have received a copy of the GNU General Public License and 23a copy of the GCC Runtime Library Exception along with this program; 24see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 25<http://www.gnu.org/licenses/>. */ 26 27#ifndef GCC_GTHR_MIPSSDE_H 28#define GCC_GTHR_MIPSSDE_H 29 30/* MIPS SDE threading API specific definitions. 31 Easy, since the interface is pretty much one-to-one. */ 32 33#define __GTHREADS 1 34 35#include <sdethread.h> 36#include <unistd.h> 37 38#ifdef __cplusplus 39extern "C" { 40#endif 41 42typedef __sdethread_key_t __gthread_key_t; 43typedef __sdethread_once_t __gthread_once_t; 44typedef __sdethread_mutex_t __gthread_mutex_t; 45 46typedef struct { 47 long depth; 48 __sdethread_t owner; 49 __sdethread_mutex_t actual; 50} __gthread_recursive_mutex_t; 51 52#define __GTHREAD_MUTEX_INIT __SDETHREAD_MUTEX_INITIALIZER("gthr") 53#define __GTHREAD_ONCE_INIT __SDETHREAD_ONCE_INIT 54static inline int 55__gthread_recursive_mutex_init_function(__gthread_recursive_mutex_t *__mutex); 56#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function 57 58#if SUPPORTS_WEAK && GTHREAD_USE_WEAK 59# define __gthrw(name) \ 60 static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name))); 61# define __gthrw_(name) __gthrw_ ## name 62#else 63# define __gthrw(name) 64# define __gthrw_(name) name 65#endif 66 67__gthrw(__sdethread_once) 68__gthrw(__sdethread_key_create) 69__gthrw(__sdethread_key_delete) 70__gthrw(__sdethread_getspecific) 71__gthrw(__sdethread_setspecific) 72 73__gthrw(__sdethread_self) 74 75__gthrw(__sdethread_mutex_lock) 76__gthrw(__sdethread_mutex_trylock) 77__gthrw(__sdethread_mutex_unlock) 78 79__gthrw(__sdethread_mutex_init) 80 81__gthrw(__sdethread_threading) 82 83#if SUPPORTS_WEAK && GTHREAD_USE_WEAK 84 85static inline int 86__gthread_active_p (void) 87{ 88 return !!(void *)&__sdethread_threading; 89} 90 91#else /* not SUPPORTS_WEAK */ 92 93static inline int 94__gthread_active_p (void) 95{ 96 return 1; 97} 98 99#endif /* SUPPORTS_WEAK */ 100 101static inline int 102__gthread_once (__gthread_once_t *__once, void (*__func) (void)) 103{ 104 if (__gthread_active_p ()) 105 return __gthrw_(__sdethread_once) (__once, __func); 106 else 107 return -1; 108} 109 110static inline int 111__gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *)) 112{ 113 return __gthrw_(__sdethread_key_create) (__key, __dtor); 114} 115 116static inline int 117__gthread_key_delete (__gthread_key_t __key) 118{ 119 return __gthrw_(__sdethread_key_delete) (__key); 120} 121 122static inline void * 123__gthread_getspecific (__gthread_key_t __key) 124{ 125 return __gthrw_(__sdethread_getspecific) (__key); 126} 127 128static inline int 129__gthread_setspecific (__gthread_key_t __key, const void *__ptr) 130{ 131 return __gthrw_(__sdethread_setspecific) (__key, __ptr); 132} 133 134static inline int 135__gthread_mutex_destroy (__gthread_mutex_t * UNUSED(__mutex)) 136{ 137 return 0; 138} 139 140static inline int 141__gthread_mutex_lock (__gthread_mutex_t *__mutex) 142{ 143 if (__gthread_active_p ()) 144 return __gthrw_(__sdethread_mutex_lock) (__mutex); 145 else 146 return 0; 147} 148 149static inline int 150__gthread_mutex_trylock (__gthread_mutex_t *__mutex) 151{ 152 if (__gthread_active_p ()) 153 return __gthrw_(__sdethread_mutex_trylock) (__mutex); 154 else 155 return 0; 156} 157 158static inline int 159__gthread_mutex_unlock (__gthread_mutex_t *__mutex) 160{ 161 if (__gthread_active_p ()) 162 return __gthrw_(__sdethread_mutex_unlock) (__mutex); 163 else 164 return 0; 165} 166 167static inline int 168__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex) 169{ 170 __mutex->depth = 0; 171 __mutex->owner = __gthrw_(__sdethread_self) (); 172 return __gthrw_(__sdethread_mutex_init) (&__mutex->actual, NULL); 173} 174 175static inline int 176__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex) 177{ 178 if (__gthread_active_p ()) 179 { 180 __sdethread_t __me = __gthrw_(__sdethread_self) (); 181 182 if (__mutex->owner != __me) 183 { 184 __gthrw_(__sdethread_mutex_lock) (&__mutex->actual); 185 __mutex->owner = __me; 186 } 187 188 __mutex->depth++; 189 } 190 return 0; 191} 192 193static inline int 194__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex) 195{ 196 if (__gthread_active_p ()) 197 { 198 __sdethread_t __me = __gthrw_(__sdethread_self) (); 199 200 if (__mutex->owner != __me) 201 { 202 if (__gthrw_(__sdethread_mutex_trylock) (&__mutex->actual)) 203 return 1; 204 __mutex->owner = __me; 205 } 206 207 __mutex->depth++; 208 } 209 return 0; 210} 211 212static inline int 213__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex) 214{ 215 if (__gthread_active_p ()) 216 { 217 if (--__mutex->depth == 0) 218 { 219 __mutex->owner = (__sdethread_t) 0; 220 __gthrw_(__sdethread_mutex_unlock) (&__mutex->actual); 221 } 222 } 223 return 0; 224} 225 226#ifdef __cplusplus 227} 228#endif 229 230#endif /* ! GCC_GTHR_MIPSSDE_H */ 231