163d1a8abSmrg /* MIPS SDE threads compatibility routines for libgcc2 and libobjc.  */
263d1a8abSmrg /* Compile this one with gcc.  */
3*ec02198aSmrg /* Copyright (C) 2006-2020 Free Software Foundation, Inc.
463d1a8abSmrg    Contributed by Nigel Stephens <nigel@mips.com>
563d1a8abSmrg 
663d1a8abSmrg This file is part of GCC.
763d1a8abSmrg 
863d1a8abSmrg GCC is free software; you can redistribute it and/or modify it under
963d1a8abSmrg the terms of the GNU General Public License as published by the Free
1063d1a8abSmrg Software Foundation; either version 3, or (at your option) any later
1163d1a8abSmrg version.
1263d1a8abSmrg 
1363d1a8abSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1463d1a8abSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
1563d1a8abSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1663d1a8abSmrg for more details.
1763d1a8abSmrg 
1863d1a8abSmrg Under Section 7 of GPL version 3, you are granted additional
1963d1a8abSmrg permissions described in the GCC Runtime Library Exception, version
2063d1a8abSmrg 3.1, as published by the Free Software Foundation.
2163d1a8abSmrg 
2263d1a8abSmrg You should have received a copy of the GNU General Public License and
2363d1a8abSmrg a copy of the GCC Runtime Library Exception along with this program;
2463d1a8abSmrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2563d1a8abSmrg <http://www.gnu.org/licenses/>.  */
2663d1a8abSmrg 
2763d1a8abSmrg #ifndef GCC_GTHR_MIPSSDE_H
2863d1a8abSmrg #define GCC_GTHR_MIPSSDE_H
2963d1a8abSmrg 
3063d1a8abSmrg /* MIPS SDE threading API specific definitions.
3163d1a8abSmrg    Easy, since the interface is pretty much one-to-one.  */
3263d1a8abSmrg 
3363d1a8abSmrg #define __GTHREADS 1
3463d1a8abSmrg 
3563d1a8abSmrg #include <sdethread.h>
3663d1a8abSmrg #include <unistd.h>
3763d1a8abSmrg 
3863d1a8abSmrg #ifdef __cplusplus
3963d1a8abSmrg extern "C" {
4063d1a8abSmrg #endif
4163d1a8abSmrg 
4263d1a8abSmrg typedef __sdethread_key_t __gthread_key_t;
4363d1a8abSmrg typedef __sdethread_once_t __gthread_once_t;
4463d1a8abSmrg typedef __sdethread_mutex_t __gthread_mutex_t;
4563d1a8abSmrg 
4663d1a8abSmrg typedef struct {
4763d1a8abSmrg   long depth;
4863d1a8abSmrg   __sdethread_t owner;
4963d1a8abSmrg   __sdethread_mutex_t actual;
5063d1a8abSmrg } __gthread_recursive_mutex_t;
5163d1a8abSmrg 
5263d1a8abSmrg #define __GTHREAD_MUTEX_INIT __SDETHREAD_MUTEX_INITIALIZER("gthr")
5363d1a8abSmrg #define __GTHREAD_ONCE_INIT __SDETHREAD_ONCE_INIT
5463d1a8abSmrg static inline int
5563d1a8abSmrg __gthread_recursive_mutex_init_function(__gthread_recursive_mutex_t *__mutex);
5663d1a8abSmrg #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
5763d1a8abSmrg 
5863d1a8abSmrg #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
5963d1a8abSmrg # define __gthrw(name) \
6063d1a8abSmrg   static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name)));
6163d1a8abSmrg # define __gthrw_(name) __gthrw_ ## name
6263d1a8abSmrg #else
6363d1a8abSmrg # define __gthrw(name)
6463d1a8abSmrg # define __gthrw_(name) name
6563d1a8abSmrg #endif
6663d1a8abSmrg 
6763d1a8abSmrg __gthrw(__sdethread_once)
__gthrw(__sdethread_key_create)6863d1a8abSmrg __gthrw(__sdethread_key_create)
6963d1a8abSmrg __gthrw(__sdethread_key_delete)
7063d1a8abSmrg __gthrw(__sdethread_getspecific)
7163d1a8abSmrg __gthrw(__sdethread_setspecific)
7263d1a8abSmrg 
7363d1a8abSmrg __gthrw(__sdethread_self)
7463d1a8abSmrg 
7563d1a8abSmrg __gthrw(__sdethread_mutex_lock)
7663d1a8abSmrg __gthrw(__sdethread_mutex_trylock)
7763d1a8abSmrg __gthrw(__sdethread_mutex_unlock)
7863d1a8abSmrg 
7963d1a8abSmrg __gthrw(__sdethread_mutex_init)
8063d1a8abSmrg 
8163d1a8abSmrg __gthrw(__sdethread_threading)
8263d1a8abSmrg 
8363d1a8abSmrg #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
8463d1a8abSmrg 
8563d1a8abSmrg static inline int
8663d1a8abSmrg __gthread_active_p (void)
8763d1a8abSmrg {
8863d1a8abSmrg   return !!(void *)&__sdethread_threading;
8963d1a8abSmrg }
9063d1a8abSmrg 
9163d1a8abSmrg #else /* not SUPPORTS_WEAK */
9263d1a8abSmrg 
9363d1a8abSmrg static inline int
9463d1a8abSmrg __gthread_active_p (void)
9563d1a8abSmrg {
9663d1a8abSmrg   return 1;
9763d1a8abSmrg }
9863d1a8abSmrg 
9963d1a8abSmrg #endif /* SUPPORTS_WEAK */
10063d1a8abSmrg 
10163d1a8abSmrg static inline int
__gthread_once(__gthread_once_t * __once,void (* __func)(void))10263d1a8abSmrg __gthread_once (__gthread_once_t *__once, void (*__func) (void))
10363d1a8abSmrg {
10463d1a8abSmrg   if (__gthread_active_p ())
10563d1a8abSmrg     return __gthrw_(__sdethread_once) (__once, __func);
10663d1a8abSmrg   else
10763d1a8abSmrg     return -1;
10863d1a8abSmrg }
10963d1a8abSmrg 
11063d1a8abSmrg static inline int
__gthread_key_create(__gthread_key_t * __key,void (* __dtor)(void *))11163d1a8abSmrg __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
11263d1a8abSmrg {
11363d1a8abSmrg   return __gthrw_(__sdethread_key_create) (__key, __dtor);
11463d1a8abSmrg }
11563d1a8abSmrg 
11663d1a8abSmrg static inline int
__gthread_key_delete(__gthread_key_t __key)11763d1a8abSmrg __gthread_key_delete (__gthread_key_t __key)
11863d1a8abSmrg {
11963d1a8abSmrg   return __gthrw_(__sdethread_key_delete) (__key);
12063d1a8abSmrg }
12163d1a8abSmrg 
12263d1a8abSmrg static inline void *
__gthread_getspecific(__gthread_key_t __key)12363d1a8abSmrg __gthread_getspecific (__gthread_key_t __key)
12463d1a8abSmrg {
12563d1a8abSmrg   return __gthrw_(__sdethread_getspecific) (__key);
12663d1a8abSmrg }
12763d1a8abSmrg 
12863d1a8abSmrg static inline int
__gthread_setspecific(__gthread_key_t __key,const void * __ptr)12963d1a8abSmrg __gthread_setspecific (__gthread_key_t __key, const void *__ptr)
13063d1a8abSmrg {
13163d1a8abSmrg   return __gthrw_(__sdethread_setspecific) (__key, __ptr);
13263d1a8abSmrg }
13363d1a8abSmrg 
13463d1a8abSmrg static inline int
__gthread_mutex_destroy(__gthread_mutex_t * UNUSED (__mutex))13563d1a8abSmrg __gthread_mutex_destroy (__gthread_mutex_t * UNUSED(__mutex))
13663d1a8abSmrg {
13763d1a8abSmrg   return 0;
13863d1a8abSmrg }
13963d1a8abSmrg 
14063d1a8abSmrg static inline int
__gthread_mutex_lock(__gthread_mutex_t * __mutex)14163d1a8abSmrg __gthread_mutex_lock (__gthread_mutex_t *__mutex)
14263d1a8abSmrg {
14363d1a8abSmrg   if (__gthread_active_p ())
14463d1a8abSmrg     return __gthrw_(__sdethread_mutex_lock) (__mutex);
14563d1a8abSmrg   else
14663d1a8abSmrg     return 0;
14763d1a8abSmrg }
14863d1a8abSmrg 
14963d1a8abSmrg static inline int
__gthread_mutex_trylock(__gthread_mutex_t * __mutex)15063d1a8abSmrg __gthread_mutex_trylock (__gthread_mutex_t *__mutex)
15163d1a8abSmrg {
15263d1a8abSmrg   if (__gthread_active_p ())
15363d1a8abSmrg     return __gthrw_(__sdethread_mutex_trylock) (__mutex);
15463d1a8abSmrg   else
15563d1a8abSmrg     return 0;
15663d1a8abSmrg }
15763d1a8abSmrg 
15863d1a8abSmrg static inline int
__gthread_mutex_unlock(__gthread_mutex_t * __mutex)15963d1a8abSmrg __gthread_mutex_unlock (__gthread_mutex_t *__mutex)
16063d1a8abSmrg {
16163d1a8abSmrg   if (__gthread_active_p ())
16263d1a8abSmrg     return __gthrw_(__sdethread_mutex_unlock) (__mutex);
16363d1a8abSmrg   else
16463d1a8abSmrg     return 0;
16563d1a8abSmrg }
16663d1a8abSmrg 
16763d1a8abSmrg static inline int
__gthread_recursive_mutex_init_function(__gthread_recursive_mutex_t * __mutex)16863d1a8abSmrg __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
16963d1a8abSmrg {
17063d1a8abSmrg   __mutex->depth = 0;
17163d1a8abSmrg   __mutex->owner = __gthrw_(__sdethread_self) ();
17263d1a8abSmrg   return __gthrw_(__sdethread_mutex_init) (&__mutex->actual, NULL);
17363d1a8abSmrg }
17463d1a8abSmrg 
17563d1a8abSmrg static inline int
__gthread_recursive_mutex_lock(__gthread_recursive_mutex_t * __mutex)17663d1a8abSmrg __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
17763d1a8abSmrg {
17863d1a8abSmrg   if (__gthread_active_p ())
17963d1a8abSmrg     {
18063d1a8abSmrg       __sdethread_t __me = __gthrw_(__sdethread_self) ();
18163d1a8abSmrg 
18263d1a8abSmrg       if (__mutex->owner != __me)
18363d1a8abSmrg 	{
18463d1a8abSmrg 	  __gthrw_(__sdethread_mutex_lock) (&__mutex->actual);
18563d1a8abSmrg 	  __mutex->owner = __me;
18663d1a8abSmrg 	}
18763d1a8abSmrg 
18863d1a8abSmrg       __mutex->depth++;
18963d1a8abSmrg     }
19063d1a8abSmrg   return 0;
19163d1a8abSmrg }
19263d1a8abSmrg 
19363d1a8abSmrg static inline int
__gthread_recursive_mutex_trylock(__gthread_recursive_mutex_t * __mutex)19463d1a8abSmrg __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
19563d1a8abSmrg {
19663d1a8abSmrg   if (__gthread_active_p ())
19763d1a8abSmrg     {
19863d1a8abSmrg       __sdethread_t __me = __gthrw_(__sdethread_self) ();
19963d1a8abSmrg 
20063d1a8abSmrg       if (__mutex->owner != __me)
20163d1a8abSmrg 	{
20263d1a8abSmrg 	  if (__gthrw_(__sdethread_mutex_trylock) (&__mutex->actual))
20363d1a8abSmrg 	    return 1;
20463d1a8abSmrg 	  __mutex->owner = __me;
20563d1a8abSmrg 	}
20663d1a8abSmrg 
20763d1a8abSmrg       __mutex->depth++;
20863d1a8abSmrg     }
20963d1a8abSmrg   return 0;
21063d1a8abSmrg }
21163d1a8abSmrg 
21263d1a8abSmrg static inline int
__gthread_recursive_mutex_unlock(__gthread_recursive_mutex_t * __mutex)21363d1a8abSmrg __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
21463d1a8abSmrg {
21563d1a8abSmrg   if (__gthread_active_p ())
21663d1a8abSmrg     {
21763d1a8abSmrg       if (--__mutex->depth == 0)
21863d1a8abSmrg 	{
21963d1a8abSmrg 	   __mutex->owner = (__sdethread_t) 0;
22063d1a8abSmrg 	   __gthrw_(__sdethread_mutex_unlock) (&__mutex->actual);
22163d1a8abSmrg 	}
22263d1a8abSmrg     }
22363d1a8abSmrg   return 0;
22463d1a8abSmrg }
22563d1a8abSmrg 
22663d1a8abSmrg static inline int
__gthread_recursive_mutex_destroy(__gthread_recursive_mutex_t * UNUSED (__mutex))22763d1a8abSmrg __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t
22863d1a8abSmrg                                    * UNUSED(__mutex))
22963d1a8abSmrg {
23063d1a8abSmrg   return 0;
23163d1a8abSmrg }
23263d1a8abSmrg 
23363d1a8abSmrg #ifdef __cplusplus
23463d1a8abSmrg }
23563d1a8abSmrg #endif
23663d1a8abSmrg 
23763d1a8abSmrg #endif /* ! GCC_GTHR_MIPSSDE_H */
238