Subversion Repositories Kolibri OS

Rev

Rev 5134 | Details | Compare with Previous | Last modification | View Log | RSS feed

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