1/* This file is automatically generated.  DO NOT EDIT! */
2/* Generated from: 	NetBSD: mknative-gcc,v 1.45 2009/12/17 15:48:13 uebayasi Exp  */
3/* Generated from: NetBSD: mknative.common,v 1.9 2007/02/05 18:26:01 apb Exp  */
4
5/* Threads compatibility routines for libgcc2 and libobjc.  */
6/* Compile this one with gcc.  */
7/* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
8   Free Software Foundation, Inc.
9
10This file is part of GCC.
11
12GCC is free software; you can redistribute it and/or modify it under
13the terms of the GNU General Public License as published by the Free
14Software Foundation; either version 2, or (at your option) any later
15version.
16
17GCC is distributed in the hope that it will be useful, but WITHOUT ANY
18WARRANTY; without even the implied warranty of MERCHANTABILITY or
19FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20for more details.
21
22You should have received a copy of the GNU General Public License
23along with GCC; see the file COPYING.  If not, write to the Free
24Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2502110-1301, USA.  */
26
27/* As a special exception, if you link this library with other files,
28   some of which are compiled with GCC, to produce an executable,
29   this library does not by itself cause the resulting executable
30   to be covered by the GNU General Public License.
31   This exception does not however invalidate any other reasons why
32   the executable file might be covered by the GNU General Public License.  */
33
34#ifndef _GLIBCXX_GCC_GTHR_POSIX_H
35#define _GLIBCXX_GCC_GTHR_POSIX_H
36
37/* POSIX threads specific definitions.
38   Easy, since the interface is just one-to-one mapping.  */
39
40#define __GTHREADS 1
41
42/* Some implementations of <pthread.h> require this to be defined.  */
43#if !defined(_REENTRANT) && defined(__osf__)
44#define _REENTRANT 1
45#endif
46
47#include <pthread.h>
48#include <unistd.h>
49
50typedef pthread_key_t __gthread_key_t;
51typedef pthread_once_t __gthread_once_t;
52typedef pthread_mutex_t __gthread_mutex_t;
53typedef pthread_mutex_t __gthread_recursive_mutex_t;
54
55#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
56#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
57#if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
58#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
59#elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
60#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
61#else
62#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
63#endif
64
65#if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
66# ifndef __gthrw_pragma
67#  define __gthrw_pragma(pragma)
68# endif
69# ifdef __clang__
70# define __gthrw2(name,name2,type) \
71  static __typeof(type) name __attribute__ ((__weakref__(#name2))); \
72  __gthrw_pragma(weak type)
73# else
74# define __gthrw2(name,name2,type) \
75  extern __typeof(type) name __attribute__ ((__weakref__(#name2))); \
76  __gthrw_pragma(weak type)
77# endif
78# define __gthrw_(name) __gthrw_ ## name
79#else
80# define __gthrw2(name,name2,type)
81# define __gthrw_(name) name
82#endif
83
84/* Typically, __gthrw_foo is a weak reference to symbol foo.  */
85#define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
86
87/* On Tru64, /usr/include/pthread.h uses #pragma extern_prefix "__" to
88   map a subset of the POSIX pthread API to mangled versions of their
89   names.  */
90#if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
91#define __gthrw3(name) __gthrw2(__gthrw_ ## name, __ ## name, name)
92__gthrw3(pthread_once)
93__gthrw3(pthread_getspecific)
94__gthrw3(pthread_setspecific)
95__gthrw3(pthread_create)
96__gthrw3(pthread_cancel)
97__gthrw3(pthread_mutex_lock)
98__gthrw3(pthread_mutex_trylock)
99__gthrw3(pthread_mutex_unlock)
100__gthrw3(pthread_mutex_init)
101#else
102__gthrw(pthread_once)
103__gthrw(pthread_getspecific)
104__gthrw(pthread_setspecific)
105__gthrw(pthread_create)
106__gthrw(pthread_cancel)
107__gthrw(pthread_mutex_lock)
108__gthrw(pthread_mutex_trylock)
109__gthrw(pthread_mutex_unlock)
110__gthrw(pthread_mutex_init)
111#endif
112
113__gthrw(pthread_key_create)
114__gthrw(pthread_key_delete)
115__gthrw(pthread_mutexattr_init)
116__gthrw(pthread_mutexattr_settype)
117__gthrw(pthread_mutexattr_destroy)
118
119
120#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
121/* Objective-C.  */
122#if defined(__osf__) && defined(_PTHREAD_USE_MANGLED_NAMES_)
123__gthrw3(pthread_cond_broadcast)
124__gthrw3(pthread_cond_destroy)
125__gthrw3(pthread_cond_init)
126__gthrw3(pthread_cond_signal)
127__gthrw3(pthread_cond_wait)
128__gthrw3(pthread_exit)
129__gthrw3(pthread_mutex_destroy)
130__gthrw3(pthread_self)
131#else
132__gthrw(pthread_cond_broadcast)
133__gthrw(pthread_cond_destroy)
134__gthrw(pthread_cond_init)
135__gthrw(pthread_cond_signal)
136__gthrw(pthread_cond_wait)
137__gthrw(pthread_exit)
138__gthrw(pthread_mutex_destroy)
139__gthrw(pthread_self)
140#endif /* __osf__ && _PTHREAD_USE_MANGLED_NAMES_ */
141#ifdef _POSIX_PRIORITY_SCHEDULING
142#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
143__gthrw(sched_get_priority_max)
144__gthrw(sched_get_priority_min)
145#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
146#endif /* _POSIX_PRIORITY_SCHEDULING */
147__gthrw(sched_yield)
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
159static inline int
160__gthread_active_p (void)
161{
162  static void *const __gthread_active_ptr
163    = __extension__ (void *) &__gthrw_(pthread_cancel);
164  return __gthread_active_ptr != 0;
165}
166
167#else /* not __GXX_WEAK__ */
168
169static inline int
170__gthread_active_p (void)
171{
172  return 1;
173}
174
175#endif /* __GXX_WEAK__ */
176
177#ifdef _LIBOBJC
178
179/* This is the config.h file in libobjc/ */
180#include <config.h>
181
182#ifdef HAVE_SCHED_H
183# include <sched.h>
184#endif
185
186/* Key structure for maintaining thread specific storage */
187static pthread_key_t _objc_thread_storage;
188static pthread_attr_t _objc_thread_attribs;
189
190/* Thread local storage for a single thread */
191static void *thread_local_storage = NULL;
192
193/* Backend initialization functions */
194
195/* Initialize the threads subsystem.  */
196static inline int
197__gthread_objc_init_thread_system (void)
198{
199  if (__gthread_active_p ())
200    {
201      /* Initialize the thread storage key.  */
202      if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
203	{
204	  /* The normal default detach state for threads is
205	   * PTHREAD_CREATE_JOINABLE which causes threads to not die
206	   * when you think they should.  */
207	  if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
208	      && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
209					      PTHREAD_CREATE_DETACHED) == 0)
210	    return 0;
211	}
212    }
213
214  return -1;
215}
216
217/* Close the threads subsystem.  */
218static inline int
219__gthread_objc_close_thread_system (void)
220{
221  if (__gthread_active_p ()
222      && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
223      && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
224    return 0;
225
226  return -1;
227}
228
229/* Backend thread functions */
230
231/* Create a new thread of execution.  */
232static inline objc_thread_t
233__gthread_objc_thread_detach (void (*func)(void *), void *arg)
234{
235  objc_thread_t thread_id;
236  pthread_t new_thread_handle;
237
238  if (!__gthread_active_p ())
239    return NULL;
240
241  if (!(__gthrw_(pthread_create) (&new_thread_handle, NULL, (void *) func, arg)))
242    thread_id = (objc_thread_t) new_thread_handle;
243  else
244    thread_id = NULL;
245
246  return thread_id;
247}
248
249/* Set the current thread's priority.  */
250static inline int
251__gthread_objc_thread_set_priority (int priority)
252{
253  if (!__gthread_active_p ())
254    return -1;
255  else
256    {
257#ifdef _POSIX_PRIORITY_SCHEDULING
258#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
259      pthread_t thread_id = __gthrw_(pthread_self) ();
260      int policy;
261      struct sched_param params;
262      int priority_min, priority_max;
263
264      if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
265	{
266	  if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
267	    return -1;
268
269	  if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
270	    return -1;
271
272	  if (priority > priority_max)
273	    priority = priority_max;
274	  else if (priority < priority_min)
275	    priority = priority_min;
276	  params.sched_priority = priority;
277
278	  /*
279	   * The solaris 7 and several other man pages incorrectly state that
280	   * this should be a pointer to policy but pthread.h is universally
281	   * at odds with this.
282	   */
283	  if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
284	    return 0;
285	}
286#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
287#endif /* _POSIX_PRIORITY_SCHEDULING */
288      return -1;
289    }
290}
291
292/* Return the current thread's priority.  */
293static inline int
294__gthread_objc_thread_get_priority (void)
295{
296#ifdef _POSIX_PRIORITY_SCHEDULING
297#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
298  if (__gthread_active_p ())
299    {
300      int policy;
301      struct sched_param params;
302
303      if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
304	return params.sched_priority;
305      else
306	return -1;
307    }
308  else
309#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
310#endif /* _POSIX_PRIORITY_SCHEDULING */
311    return OBJC_THREAD_INTERACTIVE_PRIORITY;
312}
313
314/* Yield our process time to another thread.  */
315static inline void
316__gthread_objc_thread_yield (void)
317{
318  if (__gthread_active_p ())
319    __gthrw_(sched_yield) ();
320}
321
322/* Terminate the current thread.  */
323static inline int
324__gthread_objc_thread_exit (void)
325{
326  if (__gthread_active_p ())
327    /* exit the thread */
328    __gthrw_(pthread_exit) (&__objc_thread_exit_status);
329
330  /* Failed if we reached here */
331  return -1;
332}
333
334/* Returns an integer value which uniquely describes a thread.  */
335static inline objc_thread_t
336__gthread_objc_thread_id (void)
337{
338  if (__gthread_active_p ())
339    return (objc_thread_t) __gthrw_(pthread_self) ();
340  else
341    return (objc_thread_t) 1;
342}
343
344/* Sets the thread's local storage pointer.  */
345static inline int
346__gthread_objc_thread_set_data (void *value)
347{
348  if (__gthread_active_p ())
349    return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
350  else
351    {
352      thread_local_storage = value;
353      return 0;
354    }
355}
356
357/* Returns the thread's local storage pointer.  */
358static inline void *
359__gthread_objc_thread_get_data (void)
360{
361  if (__gthread_active_p ())
362    return __gthrw_(pthread_getspecific) (_objc_thread_storage);
363  else
364    return thread_local_storage;
365}
366
367/* Backend mutex functions */
368
369/* Allocate a mutex.  */
370static inline int
371__gthread_objc_mutex_allocate (objc_mutex_t mutex)
372{
373  if (__gthread_active_p ())
374    {
375      mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
376
377      if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
378	{
379	  objc_free (mutex->backend);
380	  mutex->backend = NULL;
381	  return -1;
382	}
383    }
384
385  return 0;
386}
387
388/* Deallocate a mutex.  */
389static inline int
390__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
391{
392  if (__gthread_active_p ())
393    {
394      int count;
395
396      /*
397       * Posix Threads specifically require that the thread be unlocked
398       * for __gthrw_(pthread_mutex_destroy) to work.
399       */
400
401      do
402	{
403	  count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
404	  if (count < 0)
405	    return -1;
406	}
407      while (count);
408
409      if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
410	return -1;
411
412      objc_free (mutex->backend);
413      mutex->backend = NULL;
414    }
415  return 0;
416}
417
418/* Grab a lock on a mutex.  */
419static inline int
420__gthread_objc_mutex_lock (objc_mutex_t mutex)
421{
422  if (__gthread_active_p ()
423      && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
424    {
425      return -1;
426    }
427
428  return 0;
429}
430
431/* Try to grab a lock on a mutex.  */
432static inline int
433__gthread_objc_mutex_trylock (objc_mutex_t mutex)
434{
435  if (__gthread_active_p ()
436      && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
437    {
438      return -1;
439    }
440
441  return 0;
442}
443
444/* Unlock the mutex */
445static inline int
446__gthread_objc_mutex_unlock (objc_mutex_t mutex)
447{
448  if (__gthread_active_p ()
449      && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
450    {
451      return -1;
452    }
453
454  return 0;
455}
456
457/* Backend condition mutex functions */
458
459/* Allocate a condition.  */
460static inline int
461__gthread_objc_condition_allocate (objc_condition_t condition)
462{
463  if (__gthread_active_p ())
464    {
465      condition->backend = objc_malloc (sizeof (pthread_cond_t));
466
467      if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
468	{
469	  objc_free (condition->backend);
470	  condition->backend = NULL;
471	  return -1;
472	}
473    }
474
475  return 0;
476}
477
478/* Deallocate a condition.  */
479static inline int
480__gthread_objc_condition_deallocate (objc_condition_t condition)
481{
482  if (__gthread_active_p ())
483    {
484      if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
485	return -1;
486
487      objc_free (condition->backend);
488      condition->backend = NULL;
489    }
490  return 0;
491}
492
493/* Wait on the condition */
494static inline int
495__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
496{
497  if (__gthread_active_p ())
498    return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
499			      (pthread_mutex_t *) mutex->backend);
500  else
501    return 0;
502}
503
504/* Wake up all threads waiting on this condition.  */
505static inline int
506__gthread_objc_condition_broadcast (objc_condition_t condition)
507{
508  if (__gthread_active_p ())
509    return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
510  else
511    return 0;
512}
513
514/* Wake up one thread waiting on this condition.  */
515static inline int
516__gthread_objc_condition_signal (objc_condition_t condition)
517{
518  if (__gthread_active_p ())
519    return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
520  else
521    return 0;
522}
523
524#else /* _LIBOBJC */
525
526static inline int
527__gthread_once (__gthread_once_t *once, void (*func) (void))
528{
529  if (__gthread_active_p ())
530    return __gthrw_(pthread_once) (once, func);
531  else
532    return -1;
533}
534
535static inline int
536__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
537{
538  return __gthrw_(pthread_key_create) (key, dtor);
539}
540
541static inline int
542__gthread_key_delete (__gthread_key_t key)
543{
544  return __gthrw_(pthread_key_delete) (key);
545}
546
547static inline void *
548__gthread_getspecific (__gthread_key_t key)
549{
550  return __gthrw_(pthread_getspecific) (key);
551}
552
553static inline int
554__gthread_setspecific (__gthread_key_t key, const void *ptr)
555{
556  return __gthrw_(pthread_setspecific) (key, ptr);
557}
558
559static inline int
560__gthread_mutex_lock (__gthread_mutex_t *mutex)
561{
562  if (__gthread_active_p ())
563    return __gthrw_(pthread_mutex_lock) (mutex);
564  else
565    return 0;
566}
567
568static inline int
569__gthread_mutex_trylock (__gthread_mutex_t *mutex)
570{
571  if (__gthread_active_p ())
572    return __gthrw_(pthread_mutex_trylock) (mutex);
573  else
574    return 0;
575}
576
577static inline int
578__gthread_mutex_unlock (__gthread_mutex_t *mutex)
579{
580  if (__gthread_active_p ())
581    return __gthrw_(pthread_mutex_unlock) (mutex);
582  else
583    return 0;
584}
585
586#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
587static inline int
588__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
589{
590  if (__gthread_active_p ())
591    {
592      pthread_mutexattr_t attr;
593      int r;
594
595      r = __gthrw_(pthread_mutexattr_init) (&attr);
596      if (!r)
597	r = __gthrw_(pthread_mutexattr_settype) (&attr, PTHREAD_MUTEX_RECURSIVE);
598      if (!r)
599	r = __gthrw_(pthread_mutex_init) (mutex, &attr);
600      if (!r)
601	r = __gthrw_(pthread_mutexattr_destroy) (&attr);
602      return r;
603    }
604  return 0;
605}
606#endif
607
608static inline int
609__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
610{
611  return __gthread_mutex_lock (mutex);
612}
613
614static inline int
615__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
616{
617  return __gthread_mutex_trylock (mutex);
618}
619
620static inline int
621__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
622{
623  return __gthread_mutex_unlock (mutex);
624}
625
626#endif /* _LIBOBJC */
627
628#endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */
629