OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [gthr-posix95.h] - Blame information for rev 816

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* Threads compatibility routines for libgcc2 and libobjc.  */
2
/* Compile this one with gcc.  */
3
/* Copyright (C) 2004, 2005 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 2, 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
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING.  If not, write to the Free
19
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301, USA.  */
21
 
22
/* As a special exception, if you link this library with other files,
23
   some of which are compiled with GCC, to produce an executable,
24
   this library does not by itself cause the resulting executable
25
   to be covered by the GNU General Public License.
26
   This exception does not however invalidate any other reasons why
27
   the executable file might be covered by the GNU General Public License.  */
28
 
29
#ifndef GCC_GTHR_POSIX_H
30
#define GCC_GTHR_POSIX_H
31
 
32
/* POSIX threads specific definitions.
33
   Easy, since the interface is just one-to-one mapping.  */
34
 
35
#define __GTHREADS 1
36
 
37
/* Some implementations of <pthread.h> require this to be defined.  */
38
#ifndef _REENTRANT
39
#define _REENTRANT 1
40
#endif
41
 
42
#include <pthread.h>
43
#include <unistd.h>
44
 
45
typedef pthread_key_t __gthread_key_t;
46
typedef pthread_once_t __gthread_once_t;
47
typedef pthread_mutex_t __gthread_mutex_t;
48
 
49
typedef struct {
50
  long depth;
51
  pthread_t owner;
52
  pthread_mutex_t actual;
53
} __gthread_recursive_mutex_t;
54
 
55
#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
56
#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
57
#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
58
 
59
#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
60
# define __gthrw(name) \
61
  static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name)));
62
# define __gthrw_(name) __gthrw_ ## name
63
#else
64
# define __gthrw(name)
65
# define __gthrw_(name) name
66
#endif
67
 
68
__gthrw(pthread_once)
69
__gthrw(pthread_key_create)
70
__gthrw(pthread_key_delete)
71
__gthrw(pthread_getspecific)
72
__gthrw(pthread_setspecific)
73
__gthrw(pthread_create)
74
__gthrw(pthread_cancel)
75
__gthrw(pthread_self)
76
 
77
__gthrw(pthread_mutex_lock)
78
__gthrw(pthread_mutex_trylock)
79
__gthrw(pthread_mutex_unlock)
80
__gthrw(pthread_mutexattr_init)
81
__gthrw(pthread_mutexattr_destroy)
82
 
83
__gthrw(pthread_mutex_init)
84
 
85
#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
86
/* Objective-C.  */
87
__gthrw(pthread_cond_broadcast)
88
__gthrw(pthread_cond_destroy)
89
__gthrw(pthread_cond_init)
90
__gthrw(pthread_cond_signal)
91
__gthrw(pthread_cond_wait)
92
__gthrw(pthread_exit)
93
__gthrw(pthread_mutex_destroy)
94
#ifdef _POSIX_PRIORITY_SCHEDULING
95
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
96
__gthrw(sched_get_priority_max)
97
__gthrw(sched_get_priority_min)
98
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
99
#endif /* _POSIX_PRIORITY_SCHEDULING */
100
__gthrw(sched_yield)
101
__gthrw(pthread_attr_destroy)
102
__gthrw(pthread_attr_init)
103
__gthrw(pthread_attr_setdetachstate)
104
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
105
__gthrw(pthread_getschedparam)
106
__gthrw(pthread_setschedparam)
107
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
108
#endif /* _LIBOBJC || _LIBOBJC_WEAK */
109
 
110
#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
111
 
112
/* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if
113
   -pthreads is not specified.  The functions are dummies and most return an
114
   error value.  However pthread_once returns 0 without invoking the routine
115
   it is passed so we cannot pretend that the interface is active if -pthreads
116
   is not specified.  On Solaris 2.5.1, the interface is not exposed at all so
117
   we need to play the usual game with weak symbols.  On Solaris 10 and up, a
118
   working interface is always exposed.  */
119
 
120
#if defined(__sun) && defined(__svr4__)
121
 
122
static volatile int __gthread_active = -1;
123
 
124
static void
125
__gthread_trigger (void)
126
{
127
  __gthread_active = 1;
128
}
129
 
130
static inline int
131
__gthread_active_p (void)
132
{
133
  static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
134
  static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
135
 
136
  /* Avoid reading __gthread_active twice on the main code path.  */
137
  int __gthread_active_latest_value = __gthread_active;
138
 
139
  /* This test is not protected to avoid taking a lock on the main code
140
     path so every update of __gthread_active in a threaded program must
141
     be atomic with regard to the result of the test.  */
142
  if (__builtin_expect (__gthread_active_latest_value < 0, 0))
143
    {
144
      if (__gthrw_(pthread_once))
145
        {
146
          /* If this really is a threaded program, then we must ensure that
147
             __gthread_active has been set to 1 before exiting this block.  */
148
          __gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
149
          __gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
150
          __gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
151
        }
152
 
153
      /* Make sure we'll never enter this block again.  */
154
      if (__gthread_active < 0)
155
        __gthread_active = 0;
156
 
157
      __gthread_active_latest_value = __gthread_active;
158
    }
159
 
160
  return __gthread_active_latest_value != 0;
161
}
162
 
163
#else /* not Solaris */
164
 
165
static inline int
166
__gthread_active_p (void)
167
{
168
  static void *const __gthread_active_ptr
169
    = __extension__ (void *) &__gthrw_(pthread_cancel);
170
  return __gthread_active_ptr != 0;
171
}
172
 
173
#endif /* Solaris */
174
 
175
#else /* not SUPPORTS_WEAK */
176
 
177
static inline int
178
__gthread_active_p (void)
179
{
180
  return 1;
181
}
182
 
183
#endif /* SUPPORTS_WEAK */
184
 
185
#ifdef _LIBOBJC
186
 
187
/* This is the config.h file in libobjc/ */
188
#include <config.h>
189
 
190
#ifdef HAVE_SCHED_H
191
# include <sched.h>
192
#endif
193
 
194
/* Key structure for maintaining thread specific storage */
195
static pthread_key_t _objc_thread_storage;
196
static pthread_attr_t _objc_thread_attribs;
197
 
198
/* Thread local storage for a single thread */
199
static void *thread_local_storage = NULL;
200
 
201
/* Backend initialization functions */
202
 
203
/* Initialize the threads subsystem.  */
204
static inline int
205
__gthread_objc_init_thread_system (void)
206
{
207
  if (__gthread_active_p ())
208
    {
209
      /* Initialize the thread storage key.  */
210
      if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
211
        {
212
          /* The normal default detach state for threads is
213
           * PTHREAD_CREATE_JOINABLE which causes threads to not die
214
           * when you think they should.  */
215
          if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
216
              && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
217
                                              PTHREAD_CREATE_DETACHED) == 0)
218
            return 0;
219
        }
220
    }
221
 
222
  return -1;
223
}
224
 
225
/* Close the threads subsystem.  */
226
static inline int
227
__gthread_objc_close_thread_system (void)
228
{
229
  if (__gthread_active_p ()
230
      && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
231
      && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
232
    return 0;
233
 
234
  return -1;
235
}
236
 
237
/* Backend thread functions */
238
 
239
/* Create a new thread of execution.  */
240
static inline objc_thread_t
241
__gthread_objc_thread_detach (void (*func)(void *), void *arg)
242
{
243
  objc_thread_t thread_id;
244
  pthread_t new_thread_handle;
245
 
246
  if (!__gthread_active_p ())
247
    return NULL;
248
 
249
  if (!(__gthrw_(pthread_create) (&new_thread_handle, NULL, (void *) func, arg)))
250
    thread_id = (objc_thread_t) new_thread_handle;
251
  else
252
    thread_id = NULL;
253
 
254
  return thread_id;
255
}
256
 
257
/* Set the current thread's priority.  */
258
static inline int
259
__gthread_objc_thread_set_priority (int priority)
260
{
261
  if (!__gthread_active_p ())
262
    return -1;
263
  else
264
    {
265
#ifdef _POSIX_PRIORITY_SCHEDULING
266
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
267
      pthread_t thread_id = __gthrw_(pthread_self) ();
268
      int policy;
269
      struct sched_param params;
270
      int priority_min, priority_max;
271
 
272
      if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
273
        {
274
          if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
275
            return -1;
276
 
277
          if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
278
            return -1;
279
 
280
          if (priority > priority_max)
281
            priority = priority_max;
282
          else if (priority < priority_min)
283
            priority = priority_min;
284
          params.sched_priority = priority;
285
 
286
          /*
287
           * The solaris 7 and several other man pages incorrectly state that
288
           * this should be a pointer to policy but pthread.h is universally
289
           * at odds with this.
290
           */
291
          if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
292
            return 0;
293
        }
294
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
295
#endif /* _POSIX_PRIORITY_SCHEDULING */
296
      return -1;
297
    }
298
}
299
 
300
/* Return the current thread's priority.  */
301
static inline int
302
__gthread_objc_thread_get_priority (void)
303
{
304
#ifdef _POSIX_PRIORITY_SCHEDULING
305
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
306
  if (__gthread_active_p ())
307
    {
308
      int policy;
309
      struct sched_param params;
310
 
311
      if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
312
        return params.sched_priority;
313
      else
314
        return -1;
315
    }
316
  else
317
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
318
#endif /* _POSIX_PRIORITY_SCHEDULING */
319
    return OBJC_THREAD_INTERACTIVE_PRIORITY;
320
}
321
 
322
/* Yield our process time to another thread.  */
323
static inline void
324
__gthread_objc_thread_yield (void)
325
{
326
  if (__gthread_active_p ())
327
    __gthrw_(sched_yield) ();
328
}
329
 
330
/* Terminate the current thread.  */
331
static inline int
332
__gthread_objc_thread_exit (void)
333
{
334
  if (__gthread_active_p ())
335
    /* exit the thread */
336
    __gthrw_(pthread_exit) (&__objc_thread_exit_status);
337
 
338
  /* Failed if we reached here */
339
  return -1;
340
}
341
 
342
/* Returns an integer value which uniquely describes a thread.  */
343
static inline objc_thread_t
344
__gthread_objc_thread_id (void)
345
{
346
  if (__gthread_active_p ())
347
    return (objc_thread_t) __gthrw_(pthread_self) ();
348
  else
349
    return (objc_thread_t) 1;
350
}
351
 
352
/* Sets the thread's local storage pointer.  */
353
static inline int
354
__gthread_objc_thread_set_data (void *value)
355
{
356
  if (__gthread_active_p ())
357
    return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
358
  else
359
    {
360
      thread_local_storage = value;
361
      return 0;
362
    }
363
}
364
 
365
/* Returns the thread's local storage pointer.  */
366
static inline void *
367
__gthread_objc_thread_get_data (void)
368
{
369
  if (__gthread_active_p ())
370
    return __gthrw_(pthread_getspecific) (_objc_thread_storage);
371
  else
372
    return thread_local_storage;
373
}
374
 
375
/* Backend mutex functions */
376
 
377
/* Allocate a mutex.  */
378
static inline int
379
__gthread_objc_mutex_allocate (objc_mutex_t mutex)
380
{
381
  if (__gthread_active_p ())
382
    {
383
      mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
384
 
385
      if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
386
        {
387
          objc_free (mutex->backend);
388
          mutex->backend = NULL;
389
          return -1;
390
        }
391
    }
392
 
393
  return 0;
394
}
395
 
396
/* Deallocate a mutex.  */
397
static inline int
398
__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
399
{
400
  if (__gthread_active_p ())
401
    {
402
      int count;
403
 
404
      /*
405
       * Posix Threads specifically require that the thread be unlocked
406
       * for __gthrw_(pthread_mutex_destroy) to work.
407
       */
408
 
409
      do
410
        {
411
          count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
412
          if (count < 0)
413
            return -1;
414
        }
415
      while (count);
416
 
417
      if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
418
        return -1;
419
 
420
      objc_free (mutex->backend);
421
      mutex->backend = NULL;
422
    }
423
  return 0;
424
}
425
 
426
/* Grab a lock on a mutex.  */
427
static inline int
428
__gthread_objc_mutex_lock (objc_mutex_t mutex)
429
{
430
  if (__gthread_active_p ()
431
      && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
432
    {
433
      return -1;
434
    }
435
 
436
  return 0;
437
}
438
 
439
/* Try to grab a lock on a mutex.  */
440
static inline int
441
__gthread_objc_mutex_trylock (objc_mutex_t mutex)
442
{
443
  if (__gthread_active_p ()
444
      && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
445
    {
446
      return -1;
447
    }
448
 
449
  return 0;
450
}
451
 
452
/* Unlock the mutex */
453
static inline int
454
__gthread_objc_mutex_unlock (objc_mutex_t mutex)
455
{
456
  if (__gthread_active_p ()
457
      && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
458
    {
459
      return -1;
460
    }
461
 
462
  return 0;
463
}
464
 
465
/* Backend condition mutex functions */
466
 
467
/* Allocate a condition.  */
468
static inline int
469
__gthread_objc_condition_allocate (objc_condition_t condition)
470
{
471
  if (__gthread_active_p ())
472
    {
473
      condition->backend = objc_malloc (sizeof (pthread_cond_t));
474
 
475
      if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
476
        {
477
          objc_free (condition->backend);
478
          condition->backend = NULL;
479
          return -1;
480
        }
481
    }
482
 
483
  return 0;
484
}
485
 
486
/* Deallocate a condition.  */
487
static inline int
488
__gthread_objc_condition_deallocate (objc_condition_t condition)
489
{
490
  if (__gthread_active_p ())
491
    {
492
      if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
493
        return -1;
494
 
495
      objc_free (condition->backend);
496
      condition->backend = NULL;
497
    }
498
  return 0;
499
}
500
 
501
/* Wait on the condition */
502
static inline int
503
__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
504
{
505
  if (__gthread_active_p ())
506
    return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
507
                              (pthread_mutex_t *) mutex->backend);
508
  else
509
    return 0;
510
}
511
 
512
/* Wake up all threads waiting on this condition.  */
513
static inline int
514
__gthread_objc_condition_broadcast (objc_condition_t condition)
515
{
516
  if (__gthread_active_p ())
517
    return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
518
  else
519
    return 0;
520
}
521
 
522
/* Wake up one thread waiting on this condition.  */
523
static inline int
524
__gthread_objc_condition_signal (objc_condition_t condition)
525
{
526
  if (__gthread_active_p ())
527
    return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
528
  else
529
    return 0;
530
}
531
 
532
#else /* _LIBOBJC */
533
 
534
static inline int
535
__gthread_once (__gthread_once_t *once, void (*func) (void))
536
{
537
  if (__gthread_active_p ())
538
    return __gthrw_(pthread_once) (once, func);
539
  else
540
    return -1;
541
}
542
 
543
static inline int
544
__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
545
{
546
  return __gthrw_(pthread_key_create) (key, dtor);
547
}
548
 
549
static inline int
550
__gthread_key_delete (__gthread_key_t key)
551
{
552
  return __gthrw_(pthread_key_delete) (key);
553
}
554
 
555
static inline void *
556
__gthread_getspecific (__gthread_key_t key)
557
{
558
  return __gthrw_(pthread_getspecific) (key);
559
}
560
 
561
static inline int
562
__gthread_setspecific (__gthread_key_t key, const void *ptr)
563
{
564
  return __gthrw_(pthread_setspecific) (key, ptr);
565
}
566
 
567
static inline int
568
__gthread_mutex_lock (__gthread_mutex_t *mutex)
569
{
570
  if (__gthread_active_p ())
571
    return __gthrw_(pthread_mutex_lock) (mutex);
572
  else
573
    return 0;
574
}
575
 
576
static inline int
577
__gthread_mutex_trylock (__gthread_mutex_t *mutex)
578
{
579
  if (__gthread_active_p ())
580
    return __gthrw_(pthread_mutex_trylock) (mutex);
581
  else
582
    return 0;
583
}
584
 
585
static inline int
586
__gthread_mutex_unlock (__gthread_mutex_t *mutex)
587
{
588
  if (__gthread_active_p ())
589
    return __gthrw_(pthread_mutex_unlock) (mutex);
590
  else
591
    return 0;
592
}
593
 
594
static inline int
595
__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
596
{
597
  mutex->depth = 0;
598
  mutex->owner = (pthread_t) 0;
599
  return __gthrw_(pthread_mutex_init) (&mutex->actual, NULL);
600
}
601
 
602
static inline int
603
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
604
{
605
  if (__gthread_active_p ())
606
    {
607
      pthread_t me = __gthrw_(pthread_self) ();
608
 
609
      if (mutex->owner != me)
610
        {
611
          __gthrw_(pthread_mutex_lock) (&mutex->actual);
612
          mutex->owner = me;
613
        }
614
 
615
      mutex->depth++;
616
    }
617
  return 0;
618
}
619
 
620
static inline int
621
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
622
{
623
  if (__gthread_active_p ())
624
    {
625
      pthread_t me = __gthrw_(pthread_self) ();
626
 
627
      if (mutex->owner != me)
628
        {
629
          if (__gthrw_(pthread_mutex_trylock) (&mutex->actual))
630
            return 1;
631
          mutex->owner = me;
632
        }
633
 
634
      mutex->depth++;
635
    }
636
  return 0;
637
}
638
 
639
static inline int
640
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
641
{
642
  if (__gthread_active_p ())
643
    {
644
      if (--mutex->depth == 0)
645
        {
646
           mutex->owner = (pthread_t) 0;
647
           __gthrw_(pthread_mutex_unlock) (&mutex->actual);
648
        }
649
    }
650
  return 0;
651
}
652
 
653
#endif /* _LIBOBJC */
654
 
655
#endif /* ! GCC_GTHR_POSIX_H */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.