1 /* MIPS SDE threads compatibility routines for libgcc2 and libobjc.  */
2 /* Compile this one with gcc.  */
3 /* Copyright (C) 2006-2020 Free Software Foundation, Inc.
4    Contributed by Nigel Stephens <nigel@mips.com>
5 
6 This file is part of GCC.
7 
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12 
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17 
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
21 
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see 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
39 extern "C" {
40 #endif
41 
42 typedef __sdethread_key_t __gthread_key_t;
43 typedef __sdethread_once_t __gthread_once_t;
44 typedef __sdethread_mutex_t __gthread_mutex_t;
45 
46 typedef 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
54 static 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)
__gthrw(__sdethread_key_create)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 
85 static inline int
86 __gthread_active_p (void)
87 {
88   return !!(void *)&__sdethread_threading;
89 }
90 
91 #else /* not SUPPORTS_WEAK */
92 
93 static inline int
94 __gthread_active_p (void)
95 {
96   return 1;
97 }
98 
99 #endif /* SUPPORTS_WEAK */
100 
101 static inline int
__gthread_once(__gthread_once_t * __once,void (* __func)(void))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 
110 static inline int
__gthread_key_create(__gthread_key_t * __key,void (* __dtor)(void *))111 __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
112 {
113   return __gthrw_(__sdethread_key_create) (__key, __dtor);
114 }
115 
116 static inline int
__gthread_key_delete(__gthread_key_t __key)117 __gthread_key_delete (__gthread_key_t __key)
118 {
119   return __gthrw_(__sdethread_key_delete) (__key);
120 }
121 
122 static inline void *
__gthread_getspecific(__gthread_key_t __key)123 __gthread_getspecific (__gthread_key_t __key)
124 {
125   return __gthrw_(__sdethread_getspecific) (__key);
126 }
127 
128 static inline int
__gthread_setspecific(__gthread_key_t __key,const void * __ptr)129 __gthread_setspecific (__gthread_key_t __key, const void *__ptr)
130 {
131   return __gthrw_(__sdethread_setspecific) (__key, __ptr);
132 }
133 
134 static inline int
__gthread_mutex_destroy(__gthread_mutex_t * UNUSED (__mutex))135 __gthread_mutex_destroy (__gthread_mutex_t * UNUSED(__mutex))
136 {
137   return 0;
138 }
139 
140 static inline int
__gthread_mutex_lock(__gthread_mutex_t * __mutex)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 
149 static inline int
__gthread_mutex_trylock(__gthread_mutex_t * __mutex)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 
158 static inline int
__gthread_mutex_unlock(__gthread_mutex_t * __mutex)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 
167 static inline int
__gthread_recursive_mutex_init_function(__gthread_recursive_mutex_t * __mutex)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 
175 static inline int
__gthread_recursive_mutex_lock(__gthread_recursive_mutex_t * __mutex)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 
193 static inline int
__gthread_recursive_mutex_trylock(__gthread_recursive_mutex_t * __mutex)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 
212 static inline int
__gthread_recursive_mutex_unlock(__gthread_recursive_mutex_t * __mutex)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 static inline int
__gthread_recursive_mutex_destroy(__gthread_recursive_mutex_t * UNUSED (__mutex))227 __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t
228                                    * UNUSED(__mutex))
229 {
230   return 0;
231 }
232 
233 #ifdef __cplusplus
234 }
235 #endif
236 
237 #endif /* ! GCC_GTHR_MIPSSDE_H */
238