libstdc++
gthr-posix.h
1 /* Threads compatibility routines for libgcc2 and libobjc. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1997-2022 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 _GLIBCXX_GCC_GTHR_POSIX_H
27 #define _GLIBCXX_GCC_GTHR_POSIX_H
28 
29 /* POSIX threads specific definitions.
30  Easy, since the interface is just one-to-one mapping. */
31 
32 #define __GTHREADS 1
33 #define __GTHREADS_CXX0X 1
34 
35 #include <pthread.h>
36 
37 #if ((defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)) \
38  || !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK))
39 # include <unistd.h>
40 # if defined(_POSIX_TIMEOUTS) && _POSIX_TIMEOUTS >= 0
41 # define _GTHREAD_USE_MUTEX_TIMEDLOCK 1
42 # else
43 # define _GTHREAD_USE_MUTEX_TIMEDLOCK 0
44 # endif
45 #endif
46 
47 typedef pthread_t __gthread_t;
48 typedef pthread_key_t __gthread_key_t;
49 typedef pthread_once_t __gthread_once_t;
50 typedef pthread_mutex_t __gthread_mutex_t;
51 typedef pthread_mutex_t __gthread_recursive_mutex_t;
52 typedef pthread_cond_t __gthread_cond_t;
53 typedef struct timespec __gthread_time_t;
54 
55 /* POSIX like conditional variables are supported. Please look at comments
56  in gthr.h for details. */
57 #define __GTHREAD_HAS_COND 1
58 
59 #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
60 #define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
61 #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
62 #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
63 #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
64 #elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
65 #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
66 #else
67 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
68 #endif
69 #define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER
70 #define __GTHREAD_TIME_INIT {0,0}
71 
72 #ifdef _GTHREAD_USE_MUTEX_INIT_FUNC
73 # undef __GTHREAD_MUTEX_INIT
74 #endif
75 #ifdef _GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC
76 # undef __GTHREAD_RECURSIVE_MUTEX_INIT
77 # undef __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION
78 # define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
79 #endif
80 #ifdef _GTHREAD_USE_COND_INIT_FUNC
81 # undef __GTHREAD_COND_INIT
82 # define __GTHREAD_COND_INIT_FUNCTION __gthread_cond_init_function
83 #endif
84 
85 #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
86 # ifndef __gthrw_pragma
87 # define __gthrw_pragma(pragma)
88 # endif
89 # define __gthrw2(name,name2,type) \
90  static __typeof(type) name \
91  __attribute__ ((__weakref__(#name2), __copy__ (type))); \
92  __gthrw_pragma(weak type)
93 # define __gthrw_(name) __gthrw_ ## name
94 #else
95 # define __gthrw2(name,name2,type)
96 # define __gthrw_(name) name
97 #endif
98 
99 /* Typically, __gthrw_foo is a weak reference to symbol foo. */
100 #define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
101 
102 __gthrw(pthread_once)
103 __gthrw(pthread_getspecific)
104 __gthrw(pthread_setspecific)
105 
106 __gthrw(pthread_create)
107 __gthrw(pthread_join)
108 __gthrw(pthread_equal)
109 __gthrw(pthread_self)
110 __gthrw(pthread_detach)
111 #ifndef __BIONIC__
112 __gthrw(pthread_cancel)
113 #endif
114 __gthrw(sched_yield)
115 
116 __gthrw(pthread_mutex_lock)
117 __gthrw(pthread_mutex_trylock)
118 #if _GTHREAD_USE_MUTEX_TIMEDLOCK
119 __gthrw(pthread_mutex_timedlock)
120 #endif
121 __gthrw(pthread_mutex_unlock)
122 __gthrw(pthread_mutex_init)
123 __gthrw(pthread_mutex_destroy)
124 
125 __gthrw(pthread_cond_init)
126 __gthrw(pthread_cond_broadcast)
127 __gthrw(pthread_cond_signal)
128 __gthrw(pthread_cond_wait)
129 __gthrw(pthread_cond_timedwait)
130 __gthrw(pthread_cond_destroy)
131 
132 __gthrw(pthread_key_create)
133 __gthrw(pthread_key_delete)
134 __gthrw(pthread_mutexattr_init)
135 __gthrw(pthread_mutexattr_settype)
136 __gthrw(pthread_mutexattr_destroy)
137 
138 
139 #if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
140 /* Objective-C. */
141 __gthrw(pthread_exit)
142 #ifdef _POSIX_PRIORITY_SCHEDULING
143 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
144 __gthrw(sched_get_priority_max)
145 __gthrw(sched_get_priority_min)
146 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
147 #endif /* _POSIX_PRIORITY_SCHEDULING */
148 __gthrw(pthread_attr_destroy)
149 __gthrw(pthread_attr_init)
150 __gthrw(pthread_attr_setdetachstate)
151 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
152 __gthrw(pthread_getschedparam)
153 __gthrw(pthread_setschedparam)
154 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
155 #endif /* _LIBOBJC || _LIBOBJC_WEAK */
156 
157 #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
158 
159 /* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if
160  -pthreads is not specified. The functions are dummies and most return an
161  error value. However pthread_once returns 0 without invoking the routine
162  it is passed so we cannot pretend that the interface is active if -pthreads
163  is not specified. On Solaris 2.5.1, the interface is not exposed at all so
164  we need to play the usual game with weak symbols. On Solaris 10 and up, a
165  working interface is always exposed. On FreeBSD 6 and later, libc also
166  exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up
167  to 9 does. FreeBSD >= 700014 even provides a pthread_cancel stub in libc,
168  which means the alternate __gthread_active_p below cannot be used there. */
169 
170 #if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__))
171 
172 static volatile int __gthread_active = -1;
173 
174 static void
175 __gthread_trigger (void)
176 {
177  __gthread_active = 1;
178 }
179 
180 static inline int
181 __gthread_active_p (void)
182 {
183  static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
184  static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
185 
186  /* Avoid reading __gthread_active twice on the main code path. */
187  int __gthread_active_latest_value = __gthread_active;
188 
189  /* This test is not protected to avoid taking a lock on the main code
190  path so every update of __gthread_active in a threaded program must
191  be atomic with regard to the result of the test. */
192  if (__builtin_expect (__gthread_active_latest_value < 0, 0))
193  {
194  if (__gthrw_(pthread_once))
195  {
196  /* If this really is a threaded program, then we must ensure that
197  __gthread_active has been set to 1 before exiting this block. */
198  __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
199  __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
200  __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
201  }
202 
203  /* Make sure we'll never enter this block again. */
204  if (__gthread_active < 0)
205  __gthread_active = 0;
206 
207  __gthread_active_latest_value = __gthread_active;
208  }
209 
210  return __gthread_active_latest_value != 0;
211 }
212 
213 #else /* neither FreeBSD nor Solaris */
214 
215 /* For a program to be multi-threaded the only thing that it certainly must
216  be using is pthread_create. However, there may be other libraries that
217  intercept pthread_create with their own definitions to wrap pthreads
218  functionality for some purpose. In those cases, pthread_create being
219  defined might not necessarily mean that libpthread is actually linked
220  in.
221 
222  For the GNU C library, we can use a known internal name. This is always
223  available in the ABI, but no other library would define it. That is
224  ideal, since any public pthread function might be intercepted just as
225  pthread_create might be. __pthread_key_create is an "internal"
226  implementation symbol, but it is part of the public exported ABI. Also,
227  it's among the symbols that the static libpthread.a always links in
228  whenever pthread_create is used, so there is no danger of a false
229  negative result in any statically-linked, multi-threaded program.
230 
231  For others, we choose pthread_cancel as a function that seems unlikely
232  to be redefined by an interceptor library. The bionic (Android) C
233  library does not provide pthread_cancel, so we do use pthread_create
234  there (and interceptor libraries lose). */
235 
236 #ifdef __GLIBC__
237 __gthrw2(__gthrw_(__pthread_key_create),
238  __pthread_key_create,
239  pthread_key_create)
240 # define GTHR_ACTIVE_PROXY __gthrw_(__pthread_key_create)
241 #elif defined (__BIONIC__)
242 # define GTHR_ACTIVE_PROXY __gthrw_(pthread_create)
243 #else
244 # define GTHR_ACTIVE_PROXY __gthrw_(pthread_cancel)
245 #endif
246 
247 static inline int
248 __gthread_active_p (void)
249 {
250  static void *const __gthread_active_ptr
251  = __extension__ (void *) &GTHR_ACTIVE_PROXY;
252  return __gthread_active_ptr != 0;
253 }
254 
255 #endif /* FreeBSD or Solaris */
256 
257 #else /* not __GXX_WEAK__ */
258 
259 /* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread
260  calls in shared flavors of the HP-UX C library. Most of the stubs
261  have no functionality. The details are described in the "libc cumulative
262  patch" for each subversion of HP-UX 11. There are two special interfaces
263  provided for checking whether an application is linked to a shared pthread
264  library or not. However, these interfaces aren't available in early
265  libpthread libraries. We also need a test that works for archive
266  libraries. We can't use pthread_once as some libc versions call the
267  init function. We also can't use pthread_create or pthread_attr_init
268  as these create a thread and thereby prevent changing the default stack
269  size. The function pthread_default_stacksize_np is available in both
270  the archive and shared versions of libpthread. It can be used to
271  determine the default pthread stack size. There is a stub in some
272  shared libc versions which returns a zero size if pthreads are not
273  active. We provide an equivalent stub to handle cases where libc
274  doesn't provide one. */
275 
276 #if defined(__hppa__) && defined(__hpux__)
277 
278 static volatile int __gthread_active = -1;
279 
280 static inline int
281 __gthread_active_p (void)
282 {
283  /* Avoid reading __gthread_active twice on the main code path. */
284  int __gthread_active_latest_value = __gthread_active;
285  size_t __s;
286 
287  if (__builtin_expect (__gthread_active_latest_value < 0, 0))
288  {
289  pthread_default_stacksize_np (0, &__s);
290  __gthread_active = __s ? 1 : 0;
291  __gthread_active_latest_value = __gthread_active;
292  }
293 
294  return __gthread_active_latest_value != 0;
295 }
296 
297 #else /* not hppa-hpux */
298 
299 static inline int
300 __gthread_active_p (void)
301 {
302  return 1;
303 }
304 
305 #endif /* hppa-hpux */
306 
307 #endif /* __GXX_WEAK__ */
308 
309 #ifdef _LIBOBJC
310 
311 /* This is the config.h file in libobjc/ */
312 #include <config.h>
313 
314 #ifdef HAVE_SCHED_H
315 # include <sched.h>
316 #endif
317 
318 /* Key structure for maintaining thread specific storage */
319 static pthread_key_t _objc_thread_storage;
320 static pthread_attr_t _objc_thread_attribs;
321 
322 /* Thread local storage for a single thread */
323 static void *thread_local_storage = NULL;
324 
325 /* Backend initialization functions */
326 
327 /* Initialize the threads subsystem. */
328 static inline int
329 __gthread_objc_init_thread_system (void)
330 {
331  if (__gthread_active_p ())
332  {
333  /* Initialize the thread storage key. */
334  if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
335  {
336  /* The normal default detach state for threads is
337  * PTHREAD_CREATE_JOINABLE which causes threads to not die
338  * when you think they should. */
339  if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
340  && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
341  PTHREAD_CREATE_DETACHED) == 0)
342  return 0;
343  }
344  }
345 
346  return -1;
347 }
348 
349 /* Close the threads subsystem. */
350 static inline int
351 __gthread_objc_close_thread_system (void)
352 {
353  if (__gthread_active_p ()
354  && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
355  && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
356  return 0;
357 
358  return -1;
359 }
360 
361 /* Backend thread functions */
362 
363 /* Create a new thread of execution. */
364 static inline objc_thread_t
365 __gthread_objc_thread_detach (void (*func)(void *), void *arg)
366 {
367  objc_thread_t thread_id;
368  pthread_t new_thread_handle;
369 
370  if (!__gthread_active_p ())
371  return NULL;
372 
373  if (!(__gthrw_(pthread_create) (&new_thread_handle, &_objc_thread_attribs,
374  (void *) func, arg)))
375  thread_id = (objc_thread_t) new_thread_handle;
376  else
377  thread_id = NULL;
378 
379  return thread_id;
380 }
381 
382 /* Set the current thread's priority. */
383 static inline int
384 __gthread_objc_thread_set_priority (int priority)
385 {
386  if (!__gthread_active_p ())
387  return -1;
388  else
389  {
390 #ifdef _POSIX_PRIORITY_SCHEDULING
391 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
392  pthread_t thread_id = __gthrw_(pthread_self) ();
393  int policy;
394  struct sched_param params;
395  int priority_min, priority_max;
396 
397  if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
398  {
399  if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
400  return -1;
401 
402  if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
403  return -1;
404 
405  if (priority > priority_max)
406  priority = priority_max;
407  else if (priority < priority_min)
408  priority = priority_min;
409  params.sched_priority = priority;
410 
411  /*
412  * The solaris 7 and several other man pages incorrectly state that
413  * this should be a pointer to policy but pthread.h is universally
414  * at odds with this.
415  */
416  if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
417  return 0;
418  }
419 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
420 #endif /* _POSIX_PRIORITY_SCHEDULING */
421  return -1;
422  }
423 }
424 
425 /* Return the current thread's priority. */
426 static inline int
427 __gthread_objc_thread_get_priority (void)
428 {
429 #ifdef _POSIX_PRIORITY_SCHEDULING
430 #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
431  if (__gthread_active_p ())
432  {
433  int policy;
434  struct sched_param params;
435 
436  if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
437  return params.sched_priority;
438  else
439  return -1;
440  }
441  else
442 #endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
443 #endif /* _POSIX_PRIORITY_SCHEDULING */
444  return OBJC_THREAD_INTERACTIVE_PRIORITY;
445 }
446 
447 /* Yield our process time to another thread. */
448 static inline void
449 __gthread_objc_thread_yield (void)
450 {
451  if (__gthread_active_p ())
452  __gthrw_(sched_yield) ();
453 }
454 
455 /* Terminate the current thread. */
456 static inline int
457 __gthread_objc_thread_exit (void)
458 {
459  if (__gthread_active_p ())
460  /* exit the thread */
461  __gthrw_(pthread_exit) (&__objc_thread_exit_status);
462 
463  /* Failed if we reached here */
464  return -1;
465 }
466 
467 /* Returns an integer value which uniquely describes a thread. */
468 static inline objc_thread_t
469 __gthread_objc_thread_id (void)
470 {
471  if (__gthread_active_p ())
472  return (objc_thread_t) __gthrw_(pthread_self) ();
473  else
474  return (objc_thread_t) 1;
475 }
476 
477 /* Sets the thread's local storage pointer. */
478 static inline int
479 __gthread_objc_thread_set_data (void *value)
480 {
481  if (__gthread_active_p ())
482  return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
483  else
484  {
485  thread_local_storage = value;
486  return 0;
487  }
488 }
489 
490 /* Returns the thread's local storage pointer. */
491 static inline void *
492 __gthread_objc_thread_get_data (void)
493 {
494  if (__gthread_active_p ())
495  return __gthrw_(pthread_getspecific) (_objc_thread_storage);
496  else
497  return thread_local_storage;
498 }
499 
500 /* Backend mutex functions */
501 
502 /* Allocate a mutex. */
503 static inline int
504 __gthread_objc_mutex_allocate (objc_mutex_t mutex)
505 {
506  if (__gthread_active_p ())
507  {
508  mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
509 
510  if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
511  {
512  objc_free (mutex->backend);
513  mutex->backend = NULL;
514  return -1;
515  }
516  }
517 
518  return 0;
519 }
520 
521 /* Deallocate a mutex. */
522 static inline int
523 __gthread_objc_mutex_deallocate (objc_mutex_t mutex)
524 {
525  if (__gthread_active_p ())
526  {
527  int count;
528 
529  /*
530  * Posix Threads specifically require that the thread be unlocked
531  * for __gthrw_(pthread_mutex_destroy) to work.
532  */
533 
534  do
535  {
536  count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
537  if (count < 0)
538  return -1;
539  }
540  while (count);
541 
542  if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
543  return -1;
544 
545  objc_free (mutex->backend);
546  mutex->backend = NULL;
547  }
548  return 0;
549 }
550 
551 /* Grab a lock on a mutex. */
552 static inline int
553 __gthread_objc_mutex_lock (objc_mutex_t mutex)
554 {
555  if (__gthread_active_p ()
556  && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
557  {
558  return -1;
559  }
560 
561  return 0;
562 }
563 
564 /* Try to grab a lock on a mutex. */
565 static inline int
566 __gthread_objc_mutex_trylock (objc_mutex_t mutex)
567 {
568  if (__gthread_active_p ()
569  && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
570  {
571  return -1;
572  }
573 
574  return 0;
575 }
576 
577 /* Unlock the mutex */
578 static inline int
579 __gthread_objc_mutex_unlock (objc_mutex_t mutex)
580 {
581  if (__gthread_active_p ()
582  && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
583  {
584  return -1;
585  }
586 
587  return 0;
588 }
589 
590 /* Backend condition mutex functions */
591 
592 /* Allocate a condition. */
593 static inline int
594 __gthread_objc_condition_allocate (objc_condition_t condition)
595 {
596  if (__gthread_active_p ())
597  {
598  condition->backend = objc_malloc (sizeof (pthread_cond_t));
599 
600  if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
601  {
602  objc_free (condition->backend);
603  condition->backend = NULL;
604  return -1;
605  }
606  }
607 
608  return 0;
609 }
610 
611 /* Deallocate a condition. */
612 static inline int
613 __gthread_objc_condition_deallocate (objc_condition_t condition)
614 {
615  if (__gthread_active_p ())
616  {
617  if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
618  return -1;
619 
620  objc_free (condition->backend);
621  condition->backend = NULL;
622  }
623  return 0;
624 }
625 
626 /* Wait on the condition */
627 static inline int
628 __gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
629 {
630  if (__gthread_active_p ())
631  return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
632  (pthread_mutex_t *) mutex->backend);
633  else
634  return 0;
635 }
636 
637 /* Wake up all threads waiting on this condition. */
638 static inline int
639 __gthread_objc_condition_broadcast (objc_condition_t condition)
640 {
641  if (__gthread_active_p ())
642  return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
643  else
644  return 0;
645 }
646 
647 /* Wake up one thread waiting on this condition. */
648 static inline int
649 __gthread_objc_condition_signal (objc_condition_t condition)
650 {
651  if (__gthread_active_p ())
652  return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
653  else
654  return 0;
655 }
656 
657 #else /* _LIBOBJC */
658 
659 static inline int
660 __gthread_create (__gthread_t *__threadid, void *(*__func) (void*),
661  void *__args)
662 {
663  return __gthrw_(pthread_create) (__threadid, NULL, __func, __args);
664 }
665 
666 static inline int
667 __gthread_join (__gthread_t __threadid, void **__value_ptr)
668 {
669  return __gthrw_(pthread_join) (__threadid, __value_ptr);
670 }
671 
672 static inline int
673 __gthread_detach (__gthread_t __threadid)
674 {
675  return __gthrw_(pthread_detach) (__threadid);
676 }
677 
678 static inline int
679 __gthread_equal (__gthread_t __t1, __gthread_t __t2)
680 {
681  return __gthrw_(pthread_equal) (__t1, __t2);
682 }
683 
684 static inline __gthread_t
685 __gthread_self (void)
686 {
687  return __gthrw_(pthread_self) ();
688 }
689 
690 static inline int
691 __gthread_yield (void)
692 {
693  return __gthrw_(sched_yield) ();
694 }
695 
696 static inline int
697 __gthread_once (__gthread_once_t *__once, void (*__func) (void))
698 {
699  if (__gthread_active_p ())
700  return __gthrw_(pthread_once) (__once, __func);
701  else
702  return -1;
703 }
704 
705 static inline int
706 __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
707 {
708  return __gthrw_(pthread_key_create) (__key, __dtor);
709 }
710 
711 static inline int
712 __gthread_key_delete (__gthread_key_t __key)
713 {
714  return __gthrw_(pthread_key_delete) (__key);
715 }
716 
717 static inline void *
718 __gthread_getspecific (__gthread_key_t __key)
719 {
720  return __gthrw_(pthread_getspecific) (__key);
721 }
722 
723 static inline int
724 __gthread_setspecific (__gthread_key_t __key, const void *__ptr)
725 {
726  return __gthrw_(pthread_setspecific) (__key, __ptr);
727 }
728 
729 static inline void
730 __gthread_mutex_init_function (__gthread_mutex_t *__mutex)
731 {
732  if (__gthread_active_p ())
733  __gthrw_(pthread_mutex_init) (__mutex, NULL);
734 }
735 
736 static inline int
737 __gthread_mutex_destroy (__gthread_mutex_t *__mutex)
738 {
739  if (__gthread_active_p ())
740  return __gthrw_(pthread_mutex_destroy) (__mutex);
741  else
742  return 0;
743 }
744 
745 static inline int
746 __gthread_mutex_lock (__gthread_mutex_t *__mutex)
747 {
748  if (__gthread_active_p ())
749  return __gthrw_(pthread_mutex_lock) (__mutex);
750  else
751  return 0;
752 }
753 
754 static inline int
755 __gthread_mutex_trylock (__gthread_mutex_t *__mutex)
756 {
757  if (__gthread_active_p ())
758  return __gthrw_(pthread_mutex_trylock) (__mutex);
759  else
760  return 0;
761 }
762 
763 #if _GTHREAD_USE_MUTEX_TIMEDLOCK
764 static inline int
765 __gthread_mutex_timedlock (__gthread_mutex_t *__mutex,
766  const __gthread_time_t *__abs_timeout)
767 {
768  if (__gthread_active_p ())
769  return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout);
770  else
771  return 0;
772 }
773 #endif
774 
775 static inline int
776 __gthread_mutex_unlock (__gthread_mutex_t *__mutex)
777 {
778  if (__gthread_active_p ())
779  return __gthrw_(pthread_mutex_unlock) (__mutex);
780  else
781  return 0;
782 }
783 
784 #if !defined( PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) \
785  || defined(_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC)
786 static inline int
787 __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
788 {
789  if (__gthread_active_p ())
790  {
791  pthread_mutexattr_t __attr;
792  int __r;
793 
794  __r = __gthrw_(pthread_mutexattr_init) (&__attr);
795  if (!__r)
796  __r = __gthrw_(pthread_mutexattr_settype) (&__attr,
797  PTHREAD_MUTEX_RECURSIVE);
798  if (!__r)
799  __r = __gthrw_(pthread_mutex_init) (__mutex, &__attr);
800  if (!__r)
801  __r = __gthrw_(pthread_mutexattr_destroy) (&__attr);
802  return __r;
803  }
804  return 0;
805 }
806 #endif
807 
808 static inline int
809 __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
810 {
811  return __gthread_mutex_lock (__mutex);
812 }
813 
814 static inline int
815 __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
816 {
817  return __gthread_mutex_trylock (__mutex);
818 }
819 
820 #if _GTHREAD_USE_MUTEX_TIMEDLOCK
821 static inline int
822 __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex,
823  const __gthread_time_t *__abs_timeout)
824 {
825  return __gthread_mutex_timedlock (__mutex, __abs_timeout);
826 }
827 #endif
828 
829 static inline int
830 __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
831 {
832  return __gthread_mutex_unlock (__mutex);
833 }
834 
835 static inline int
836 __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
837 {
838  return __gthread_mutex_destroy (__mutex);
839 }
840 
841 #ifdef _GTHREAD_USE_COND_INIT_FUNC
842 static inline void
843 __gthread_cond_init_function (__gthread_cond_t *__cond)
844 {
845  if (__gthread_active_p ())
846  __gthrw_(pthread_cond_init) (__cond, NULL);
847 }
848 #endif
849 
850 static inline int
851 __gthread_cond_broadcast (__gthread_cond_t *__cond)
852 {
853  return __gthrw_(pthread_cond_broadcast) (__cond);
854 }
855 
856 static inline int
857 __gthread_cond_signal (__gthread_cond_t *__cond)
858 {
859  return __gthrw_(pthread_cond_signal) (__cond);
860 }
861 
862 static inline int
863 __gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex)
864 {
865  return __gthrw_(pthread_cond_wait) (__cond, __mutex);
866 }
867 
868 static inline int
869 __gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex,
870  const __gthread_time_t *__abs_timeout)
871 {
872  return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout);
873 }
874 
875 static inline int
876 __gthread_cond_wait_recursive (__gthread_cond_t *__cond,
877  __gthread_recursive_mutex_t *__mutex)
878 {
879  return __gthread_cond_wait (__cond, __mutex);
880 }
881 
882 static inline int
883 __gthread_cond_destroy (__gthread_cond_t* __cond)
884 {
885  return __gthrw_(pthread_cond_destroy) (__cond);
886 }
887 
888 #endif /* _LIBOBJC */
889 
890 #endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */
_Tp arg(const complex< _Tp > &)
Return phase angle of z.
Definition: complex:657