(root)/
gcc-13.2.0/
libgcc/
config/
pa/
gthr-dce.h
       1  /* Threads compatibility routines for libgcc2 and libobjc.  */
       2  /* Compile this one with gcc.  */
       3  /* Copyright (C) 1997-2023 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  #ifndef GCC_GTHR_DCE_H
      27  #define GCC_GTHR_DCE_H
      28  
      29  /* If _DCE_THREADS is not defined, then we're building the single
      30     threaded version of the libraries and do not want to reference
      31     anything related to pthreads or dce.  */
      32  #ifndef _DCE_THREADS
      33  #include "gthr-single.h"
      34  #else
      35  /* DCE threads interface.
      36     DCE threads are based on POSIX threads draft 4, and many things
      37     have changed since then.  */
      38  
      39  /* Make sure CONST_CAST2 (original in system.h) is defined.  */
      40  #ifndef CONST_CAST2
      41  #ifdef __cplusplus
      42  #define CONST_CAST2(TOTYPE,FROMTYPE,X) (const_cast<TOTYPE> (X))
      43  #else
      44  #define CONST_CAST2(TOTYPE,FROMTYPE,X) ((__extension__(union {FROMTYPE _q; TOTYPE _nq;})(X))._nq)
      45  #endif
      46  #endif
      47  
      48  #define __GTHREADS 1
      49  
      50  #include <pthread.h>
      51  
      52  typedef pthread_key_t __gthread_key_t;
      53  typedef pthread_once_t __gthread_once_t;
      54  typedef pthread_mutex_t __gthread_mutex_t;
      55  typedef pthread_mutex_t __gthread_recursive_mutex_t;
      56  
      57  #define __GTHREAD_ONCE_INIT pthread_once_init
      58  
      59  #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
      60  #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
      61  
      62  #define __GTHREAD_MUTEX_INIT_DEFAULT pthread_once_init
      63  
      64  #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
      65  # define __gthrw(name) \
      66    static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name)));
      67  # define __gthrw_(name) __gthrw_ ## name
      68  #else
      69  # define __gthrw(name)
      70  # define __gthrw_(name) name
      71  #endif
      72  
      73  __gthrw(pthread_once)
      74  __gthrw(pthread_keycreate)
      75  __gthrw(pthread_getspecific)
      76  __gthrw(pthread_setspecific)
      77  __gthrw(pthread_create)
      78  __gthrw(pthread_mutex_init)
      79  __gthrw(pthread_mutex_destroy)
      80  __gthrw(pthread_mutex_lock)
      81  __gthrw(pthread_mutex_trylock)
      82  __gthrw(pthread_mutex_unlock)
      83  __gthrw(pthread_mutexattr_create)
      84  __gthrw(pthread_mutexattr_setkind_np)
      85  __gthrw(pthread_mutexattr_delete)
      86  
      87  #ifdef _LIBOBJC
      88  /* Objective-C.  */
      89  __gthrw(pthread_cond_broadcast)
      90  __gthrw(pthread_cond_destroy)
      91  __gthrw(pthread_cond_init)
      92  __gthrw(pthread_cond_signal)
      93  __gthrw(pthread_cond_wait)
      94  __gthrw(pthread_exit)
      95  
      96  #ifdef pthread_getunique_np
      97  # define __gthrw_pthread_getunique_np pthread_getunique_np
      98  #else
      99  __gthrw(pthread_getunique_np)
     100  # define __gthrw_pthread_getunique_np __gthrw_(pthread_getunique_np)
     101  #endif
     102  
     103  __gthrw(pthread_mutex_destroy)
     104  __gthrw(pthread_self)
     105  __gthrw(pthread_yield)
     106  #endif
     107  
     108  #if SUPPORTS_WEAK && GTHREAD_USE_WEAK
     109  
     110  static inline int
     111  __gthread_active_p (void)
     112  {
     113    static void *const __gthread_active_ptr = (void *) &__gthrw_(pthread_create);
     114    return __gthread_active_ptr != 0;
     115  }
     116  
     117  #else /* not SUPPORTS_WEAK */
     118  
     119  static inline int
     120  __gthread_active_p (void)
     121  {
     122    return 1;
     123  }
     124  
     125  #endif /* SUPPORTS_WEAK */
     126  
     127  #ifdef _LIBOBJC
     128  
     129  /* Key structure for maintaining thread specific storage */
     130  static pthread_key_t _objc_thread_storage;
     131  
     132  /* Thread local storage for a single thread */
     133  static void *thread_local_storage = NULL;
     134  
     135  /* Backend initialization functions */
     136  
     137  /* Initialize the threads subsystem.  */
     138  static inline int
     139  __gthread_objc_init_thread_system (void)
     140  {
     141    if (__gthread_active_p ())
     142      /* Initialize the thread storage key.  */
     143      return __gthrw_(pthread_keycreate) (&_objc_thread_storage, NULL);
     144    else
     145      return -1;
     146  }
     147  
     148  /* Close the threads subsystem.  */
     149  static inline int
     150  __gthread_objc_close_thread_system (void)
     151  {
     152    if (__gthread_active_p ())
     153      return 0;
     154    else
     155      return -1;
     156  }
     157  
     158  /* Backend thread functions */
     159  
     160  /* Create a new thread of execution.  */
     161  static inline objc_thread_t
     162  __gthread_objc_thread_detach (void (*func)(void *), void *arg)
     163  {
     164    objc_thread_t thread_id;
     165    pthread_t new_thread_handle;
     166  
     167    if (!__gthread_active_p ())
     168      return NULL;
     169  
     170    if (!(__gthrw_(pthread_create) (&new_thread_handle, pthread_attr_default,
     171  			(void *) func, arg)))
     172      {
     173        /* ??? May not work! (64bit) */
     174        thread_id = *(objc_thread_t *) &new_thread_handle;
     175        pthread_detach (&new_thread_handle); /* Fully detach thread.  */
     176      }
     177    else
     178      thread_id = NULL;
     179  
     180    return thread_id;
     181  }
     182  
     183  /* Set the current thread's priority.  */
     184  static inline int
     185  __gthread_objc_thread_set_priority (int priority)
     186  {
     187    int sys_priority = 0;
     188  
     189    if (!__gthread_active_p ())
     190      return -1;
     191  
     192    switch (priority)
     193      {
     194      case OBJC_THREAD_INTERACTIVE_PRIORITY:
     195        sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2;
     196        break;
     197      default:
     198      case OBJC_THREAD_BACKGROUND_PRIORITY:
     199        sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
     200        break;
     201      case OBJC_THREAD_LOW_PRIORITY:
     202        sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
     203        break;
     204      }
     205  
     206    /* Change the priority.  */
     207    if (pthread_setprio (__gthrw_(pthread_self) (), sys_priority) >= 0)
     208      return 0;
     209    else
     210      /* Failed */
     211      return -1;
     212  }
     213  
     214  /* Return the current thread's priority.  */
     215  static inline int
     216  __gthread_objc_thread_get_priority (void)
     217  {
     218    int sys_priority;
     219  
     220    if (__gthread_active_p ())
     221      {
     222        if ((sys_priority = pthread_getprio (__gthrw_(pthread_self) ())) >= 0)
     223  	{
     224  	  if (sys_priority >= PRI_FG_MIN_NP
     225  	      && sys_priority <= PRI_FG_MAX_NP)
     226  	    return OBJC_THREAD_INTERACTIVE_PRIORITY;
     227  	  if (sys_priority >= PRI_BG_MIN_NP
     228  	      && sys_priority <= PRI_BG_MAX_NP)
     229  	    return OBJC_THREAD_BACKGROUND_PRIORITY;
     230  	  return OBJC_THREAD_LOW_PRIORITY;
     231  	}
     232  
     233        /* Failed */
     234        return -1;
     235      }
     236    else
     237      return OBJC_THREAD_INTERACTIVE_PRIORITY;
     238  }
     239  
     240  /* Yield our process time to another thread.  */
     241  static inline void
     242  __gthread_objc_thread_yield (void)
     243  {
     244    if (__gthread_active_p ())
     245      __gthrw_(pthread_yield) ();
     246  }
     247  
     248  /* Terminate the current thread.  */
     249  static inline int
     250  __gthread_objc_thread_exit (void)
     251  {
     252    if (__gthread_active_p ())
     253      /* exit the thread */
     254      __gthrw_(pthread_exit) (&__objc_thread_exit_status);
     255  
     256    /* Failed if we reached here */
     257    return -1;
     258  }
     259  
     260  /* Returns an integer value which uniquely describes a thread.  */
     261  static inline objc_thread_t
     262  __gthread_objc_thread_id (void)
     263  {
     264    if (__gthread_active_p ())
     265      {
     266        pthread_t self = __gthrw_(pthread_self) ();
     267  
     268        return (objc_thread_t) __gthrw_pthread_getunique_np (&self);
     269      }
     270    else
     271      return (objc_thread_t) 1;
     272  }
     273  
     274  /* Sets the thread's local storage pointer.  */
     275  static inline int
     276  __gthread_objc_thread_set_data (void *value)
     277  {
     278    if (__gthread_active_p ())
     279      return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
     280    else
     281      {
     282        thread_local_storage = value;
     283        return 0;
     284      }
     285  }
     286  
     287  /* Returns the thread's local storage pointer.  */
     288  static inline void *
     289  __gthread_objc_thread_get_data (void)
     290  {
     291    void *value = NULL;
     292  
     293    if (__gthread_active_p ())
     294      {
     295        if (!(__gthrw_(pthread_getspecific) (_objc_thread_storage, &value)))
     296  	return value;
     297  
     298        return NULL;
     299      }
     300    else
     301      return thread_local_storage;
     302  }
     303  
     304  /* Backend mutex functions */
     305  
     306  /* Allocate a mutex.  */
     307  static inline int
     308  __gthread_objc_mutex_allocate (objc_mutex_t mutex)
     309  {
     310    if (__gthread_active_p ())
     311      {
     312        mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
     313  
     314        if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend,
     315  			      pthread_mutexattr_default))
     316  	{
     317  	  objc_free (mutex->backend);
     318  	  mutex->backend = NULL;
     319  	  return -1;
     320  	}
     321      }
     322  
     323    return 0;
     324  }
     325  
     326  /* Deallocate a mutex.  */
     327  static inline int
     328  __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
     329  {
     330    if (__gthread_active_p ())
     331      {
     332        if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
     333  	return -1;
     334  
     335        objc_free (mutex->backend);
     336        mutex->backend = NULL;
     337      }
     338  
     339    return 0;
     340  }
     341  
     342  /* Grab a lock on a mutex.  */
     343  static inline int
     344  __gthread_objc_mutex_lock (objc_mutex_t mutex)
     345  {
     346    if (__gthread_active_p ())
     347      return __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend);
     348    else
     349      return 0;
     350  }
     351  
     352  /* Try to grab a lock on a mutex.  */
     353  static inline int
     354  __gthread_objc_mutex_trylock (objc_mutex_t mutex)
     355  {
     356    if (__gthread_active_p ()
     357        && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 1)
     358      return -1;
     359  
     360    return 0;
     361  }
     362  
     363  /* Unlock the mutex */
     364  static inline int
     365  __gthread_objc_mutex_unlock (objc_mutex_t mutex)
     366  {
     367    if (__gthread_active_p ())
     368      return __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
     369    else
     370      return 0;
     371  }
     372  
     373  /* Backend condition mutex functions */
     374  
     375  /* Allocate a condition.  */
     376  static inline int
     377  __gthread_objc_condition_allocate (objc_condition_t condition
     378  				   __attribute__ ((__unused__)))
     379  {
     380    if (__gthread_active_p ())
     381      /* Unimplemented.  */
     382      return -1;
     383    else
     384      return 0;
     385  }
     386  
     387  /* Deallocate a condition.  */
     388  static inline int
     389  __gthread_objc_condition_deallocate (objc_condition_t condition
     390  				     __attribute__ ((__unused__)))
     391  {
     392    if (__gthread_active_p ())
     393      /* Unimplemented.  */
     394      return -1;
     395    else
     396      return 0;
     397  }
     398  
     399  /* Wait on the condition */
     400  static inline int
     401  __gthread_objc_condition_wait (objc_condition_t condition
     402  			       __attribute__ ((__unused__)),
     403  			       objc_mutex_t mutex __attribute__ ((__unused__)))
     404  {
     405    if (__gthread_active_p ())
     406      /* Unimplemented.  */
     407      return -1;
     408    else
     409      return 0;
     410  }
     411  
     412  /* Wake up all threads waiting on this condition.  */
     413  static inline int
     414  __gthread_objc_condition_broadcast (objc_condition_t condition
     415  				    __attribute__ ((__unused__)))
     416  {
     417    if (__gthread_active_p ())
     418      /* Unimplemented.  */
     419      return -1;
     420    else
     421      return 0;
     422  }
     423  
     424  /* Wake up one thread waiting on this condition.  */
     425  static inline int
     426  __gthread_objc_condition_signal (objc_condition_t condition
     427  				 __attribute__ ((__unused__)))
     428  {
     429    if (__gthread_active_p ())
     430      /* Unimplemented.  */
     431      return -1;
     432    else
     433      return 0;
     434  }
     435  
     436  #else /* _LIBOBJC */
     437  
     438  static inline int
     439  __gthread_once (__gthread_once_t *__once, void (*__func) (void))
     440  {
     441    if (__gthread_active_p ())
     442      return __gthrw_(pthread_once) (__once, __func);
     443    else
     444      return -1;
     445  }
     446  
     447  static inline int
     448  __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
     449  {
     450    return __gthrw_(pthread_keycreate) (__key, __dtor);
     451  }
     452  
     453  static inline int
     454  __gthread_key_delete (__gthread_key_t __key __attribute__ ((__unused__)))
     455  {
     456    /* Operation is not supported.  */
     457    return -1;
     458  }
     459  
     460  static inline void *
     461  __gthread_getspecific (__gthread_key_t __key)
     462  {
     463    void *__ptr;
     464    if (__gthrw_(pthread_getspecific) (__key, &__ptr) == 0)
     465      return __ptr;
     466    else
     467      return 0;
     468  }
     469  
     470  static inline int
     471  __gthread_setspecific (__gthread_key_t __key, const void *__ptr)
     472  {
     473    return __gthrw_(pthread_setspecific)
     474      (__key, CONST_CAST2(void *, const void *, __ptr));
     475  }
     476  
     477  static inline void
     478  __gthread_mutex_init_function (__gthread_mutex_t *__mutex)
     479  {
     480    if (__gthread_active_p ())
     481      __gthrw_(pthread_mutex_init) (__mutex, pthread_mutexattr_default);
     482  }
     483  
     484  static inline int
     485  __gthread_mutex_destroy (__gthread_mutex_t *__mutex)
     486  {
     487    if (__gthread_active_p ())
     488      return __gthrw_(pthread_mutex_destroy) (__mutex);
     489    else
     490      return 0;
     491  }
     492  
     493  static inline int
     494  __gthread_mutex_lock (__gthread_mutex_t *__mutex)
     495  {
     496    if (__gthread_active_p ())
     497      return __gthrw_(pthread_mutex_lock) (__mutex);
     498    else
     499      return 0;
     500  }
     501  
     502  static inline int
     503  __gthread_mutex_trylock (__gthread_mutex_t *__mutex)
     504  {
     505    if (__gthread_active_p ())
     506      return __gthrw_(pthread_mutex_trylock) (__mutex);
     507    else
     508      return 0;
     509  }
     510  
     511  static inline int
     512  __gthread_mutex_unlock (__gthread_mutex_t *__mutex)
     513  {
     514    if (__gthread_active_p ())
     515      return __gthrw_(pthread_mutex_unlock) (__mutex);
     516    else
     517      return 0;
     518  }
     519  
     520  static inline int
     521  __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
     522  {
     523    if (__gthread_active_p ())
     524      {
     525        pthread_mutexattr_t __attr;
     526        int __r;
     527  
     528        __r = __gthrw_(pthread_mutexattr_create) (&__attr);
     529        if (!__r)
     530  	__r = __gthrw_(pthread_mutexattr_setkind_np) (&__attr,
     531  						      MUTEX_RECURSIVE_NP);
     532        if (!__r)
     533  	__r = __gthrw_(pthread_mutex_init) (__mutex, __attr);
     534        if (!__r)
     535  	__r = __gthrw_(pthread_mutexattr_delete) (&__attr);
     536        return __r;
     537      }
     538    return 0;
     539  }
     540  
     541  static inline int
     542  __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
     543  {
     544    return __gthread_mutex_lock (__mutex);
     545  }
     546  
     547  static inline int
     548  __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
     549  {
     550    return __gthread_mutex_trylock (__mutex);
     551  }
     552  
     553  static inline int
     554  __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
     555  {
     556    return __gthread_mutex_unlock (__mutex);
     557  }
     558  
     559  static inline int
     560  __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
     561  {
     562    return __gthread_mutex_destroy (__mutex);
     563  }
     564  
     565  #endif /* _LIBOBJC */
     566  
     567  #endif
     568  #endif /* ! GCC_GTHR_DCE_H */