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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [gthr-posix95.h] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 12 jlechner
/* 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
  extern __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
static inline int
113
__gthread_active_p (void)
114
{
115
  static void *const __gthread_active_ptr
116
    = __extension__ (void *) &__gthrw_(pthread_cancel);
117
  return __gthread_active_ptr != 0;
118
}
119
 
120
#else /* not SUPPORTS_WEAK */
121
 
122
static inline int
123
__gthread_active_p (void)
124
{
125
  return 1;
126
}
127
 
128
#endif /* SUPPORTS_WEAK */
129
 
130
#ifdef _LIBOBJC
131
 
132
/* This is the config.h file in libobjc/ */
133
#include <config.h>
134
 
135
#ifdef HAVE_SCHED_H
136
# include <sched.h>
137
#endif
138
 
139
/* Key structure for maintaining thread specific storage */
140
static pthread_key_t _objc_thread_storage;
141
static pthread_attr_t _objc_thread_attribs;
142
 
143
/* Thread local storage for a single thread */
144
static void *thread_local_storage = NULL;
145
 
146
/* Backend initialization functions */
147
 
148
/* Initialize the threads subsystem.  */
149
static inline int
150
__gthread_objc_init_thread_system (void)
151
{
152
  if (__gthread_active_p ())
153
    {
154
      /* Initialize the thread storage key.  */
155
      if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
156
        {
157
          /* The normal default detach state for threads is
158
           * PTHREAD_CREATE_JOINABLE which causes threads to not die
159
           * when you think they should.  */
160
          if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
161
              && __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
162
                                              PTHREAD_CREATE_DETACHED) == 0)
163
            return 0;
164
        }
165
    }
166
 
167
  return -1;
168
}
169
 
170
/* Close the threads subsystem.  */
171
static inline int
172
__gthread_objc_close_thread_system (void)
173
{
174
  if (__gthread_active_p ()
175
      && __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
176
      && __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
177
    return 0;
178
 
179
  return -1;
180
}
181
 
182
/* Backend thread functions */
183
 
184
/* Create a new thread of execution.  */
185
static inline objc_thread_t
186
__gthread_objc_thread_detach (void (*func)(void *), void *arg)
187
{
188
  objc_thread_t thread_id;
189
  pthread_t new_thread_handle;
190
 
191
  if (!__gthread_active_p ())
192
    return NULL;
193
 
194
  if (!(__gthrw_(pthread_create) (&new_thread_handle, NULL, (void *) func, arg)))
195
    thread_id = (objc_thread_t) new_thread_handle;
196
  else
197
    thread_id = NULL;
198
 
199
  return thread_id;
200
}
201
 
202
/* Set the current thread's priority.  */
203
static inline int
204
__gthread_objc_thread_set_priority (int priority)
205
{
206
  if (!__gthread_active_p ())
207
    return -1;
208
  else
209
    {
210
#ifdef _POSIX_PRIORITY_SCHEDULING
211
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
212
      pthread_t thread_id = __gthrw_(pthread_self) ();
213
      int policy;
214
      struct sched_param params;
215
      int priority_min, priority_max;
216
 
217
      if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
218
        {
219
          if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
220
            return -1;
221
 
222
          if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
223
            return -1;
224
 
225
          if (priority > priority_max)
226
            priority = priority_max;
227
          else if (priority < priority_min)
228
            priority = priority_min;
229
          params.sched_priority = priority;
230
 
231
          /*
232
           * The solaris 7 and several other man pages incorrectly state that
233
           * this should be a pointer to policy but pthread.h is universally
234
           * at odds with this.
235
           */
236
          if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
237
            return 0;
238
        }
239
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
240
#endif /* _POSIX_PRIORITY_SCHEDULING */
241
      return -1;
242
    }
243
}
244
 
245
/* Return the current thread's priority.  */
246
static inline int
247
__gthread_objc_thread_get_priority (void)
248
{
249
#ifdef _POSIX_PRIORITY_SCHEDULING
250
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
251
  if (__gthread_active_p ())
252
    {
253
      int policy;
254
      struct sched_param params;
255
 
256
      if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
257
        return params.sched_priority;
258
      else
259
        return -1;
260
    }
261
  else
262
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
263
#endif /* _POSIX_PRIORITY_SCHEDULING */
264
    return OBJC_THREAD_INTERACTIVE_PRIORITY;
265
}
266
 
267
/* Yield our process time to another thread.  */
268
static inline void
269
__gthread_objc_thread_yield (void)
270
{
271
  if (__gthread_active_p ())
272
    __gthrw_(sched_yield) ();
273
}
274
 
275
/* Terminate the current thread.  */
276
static inline int
277
__gthread_objc_thread_exit (void)
278
{
279
  if (__gthread_active_p ())
280
    /* exit the thread */
281
    __gthrw_(pthread_exit) (&__objc_thread_exit_status);
282
 
283
  /* Failed if we reached here */
284
  return -1;
285
}
286
 
287
/* Returns an integer value which uniquely describes a thread.  */
288
static inline objc_thread_t
289
__gthread_objc_thread_id (void)
290
{
291
  if (__gthread_active_p ())
292
    return (objc_thread_t) __gthrw_(pthread_self) ();
293
  else
294
    return (objc_thread_t) 1;
295
}
296
 
297
/* Sets the thread's local storage pointer.  */
298
static inline int
299
__gthread_objc_thread_set_data (void *value)
300
{
301
  if (__gthread_active_p ())
302
    return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
303
  else
304
    {
305
      thread_local_storage = value;
306
      return 0;
307
    }
308
}
309
 
310
/* Returns the thread's local storage pointer.  */
311
static inline void *
312
__gthread_objc_thread_get_data (void)
313
{
314
  if (__gthread_active_p ())
315
    return __gthrw_(pthread_getspecific) (_objc_thread_storage);
316
  else
317
    return thread_local_storage;
318
}
319
 
320
/* Backend mutex functions */
321
 
322
/* Allocate a mutex.  */
323
static inline int
324
__gthread_objc_mutex_allocate (objc_mutex_t mutex)
325
{
326
  if (__gthread_active_p ())
327
    {
328
      mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
329
 
330
      if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
331
        {
332
          objc_free (mutex->backend);
333
          mutex->backend = NULL;
334
          return -1;
335
        }
336
    }
337
 
338
  return 0;
339
}
340
 
341
/* Deallocate a mutex.  */
342
static inline int
343
__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
344
{
345
  if (__gthread_active_p ())
346
    {
347
      int count;
348
 
349
      /*
350
       * Posix Threads specifically require that the thread be unlocked
351
       * for __gthrw_(pthread_mutex_destroy) to work.
352
       */
353
 
354
      do
355
        {
356
          count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
357
          if (count < 0)
358
            return -1;
359
        }
360
      while (count);
361
 
362
      if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
363
        return -1;
364
 
365
      objc_free (mutex->backend);
366
      mutex->backend = NULL;
367
    }
368
  return 0;
369
}
370
 
371
/* Grab a lock on a mutex.  */
372
static inline int
373
__gthread_objc_mutex_lock (objc_mutex_t mutex)
374
{
375
  if (__gthread_active_p ()
376
      && __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
377
    {
378
      return -1;
379
    }
380
 
381
  return 0;
382
}
383
 
384
/* Try to grab a lock on a mutex.  */
385
static inline int
386
__gthread_objc_mutex_trylock (objc_mutex_t mutex)
387
{
388
  if (__gthread_active_p ()
389
      && __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
390
    {
391
      return -1;
392
    }
393
 
394
  return 0;
395
}
396
 
397
/* Unlock the mutex */
398
static inline int
399
__gthread_objc_mutex_unlock (objc_mutex_t mutex)
400
{
401
  if (__gthread_active_p ()
402
      && __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
403
    {
404
      return -1;
405
    }
406
 
407
  return 0;
408
}
409
 
410
/* Backend condition mutex functions */
411
 
412
/* Allocate a condition.  */
413
static inline int
414
__gthread_objc_condition_allocate (objc_condition_t condition)
415
{
416
  if (__gthread_active_p ())
417
    {
418
      condition->backend = objc_malloc (sizeof (pthread_cond_t));
419
 
420
      if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
421
        {
422
          objc_free (condition->backend);
423
          condition->backend = NULL;
424
          return -1;
425
        }
426
    }
427
 
428
  return 0;
429
}
430
 
431
/* Deallocate a condition.  */
432
static inline int
433
__gthread_objc_condition_deallocate (objc_condition_t condition)
434
{
435
  if (__gthread_active_p ())
436
    {
437
      if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
438
        return -1;
439
 
440
      objc_free (condition->backend);
441
      condition->backend = NULL;
442
    }
443
  return 0;
444
}
445
 
446
/* Wait on the condition */
447
static inline int
448
__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
449
{
450
  if (__gthread_active_p ())
451
    return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
452
                              (pthread_mutex_t *) mutex->backend);
453
  else
454
    return 0;
455
}
456
 
457
/* Wake up all threads waiting on this condition.  */
458
static inline int
459
__gthread_objc_condition_broadcast (objc_condition_t condition)
460
{
461
  if (__gthread_active_p ())
462
    return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
463
  else
464
    return 0;
465
}
466
 
467
/* Wake up one thread waiting on this condition.  */
468
static inline int
469
__gthread_objc_condition_signal (objc_condition_t condition)
470
{
471
  if (__gthread_active_p ())
472
    return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
473
  else
474
    return 0;
475
}
476
 
477
#else /* _LIBOBJC */
478
 
479
static inline int
480
__gthread_once (__gthread_once_t *once, void (*func) (void))
481
{
482
  if (__gthread_active_p ())
483
    return __gthrw_(pthread_once) (once, func);
484
  else
485
    return -1;
486
}
487
 
488
static inline int
489
__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
490
{
491
  return __gthrw_(pthread_key_create) (key, dtor);
492
}
493
 
494
static inline int
495
__gthread_key_delete (__gthread_key_t key)
496
{
497
  return __gthrw_(pthread_key_delete) (key);
498
}
499
 
500
static inline void *
501
__gthread_getspecific (__gthread_key_t key)
502
{
503
  return __gthrw_(pthread_getspecific) (key);
504
}
505
 
506
static inline int
507
__gthread_setspecific (__gthread_key_t key, const void *ptr)
508
{
509
  return __gthrw_(pthread_setspecific) (key, ptr);
510
}
511
 
512
static inline int
513
__gthread_mutex_lock (__gthread_mutex_t *mutex)
514
{
515
  if (__gthread_active_p ())
516
    return __gthrw_(pthread_mutex_lock) (mutex);
517
  else
518
    return 0;
519
}
520
 
521
static inline int
522
__gthread_mutex_trylock (__gthread_mutex_t *mutex)
523
{
524
  if (__gthread_active_p ())
525
    return __gthrw_(pthread_mutex_trylock) (mutex);
526
  else
527
    return 0;
528
}
529
 
530
static inline int
531
__gthread_mutex_unlock (__gthread_mutex_t *mutex)
532
{
533
  if (__gthread_active_p ())
534
    return __gthrw_(pthread_mutex_unlock) (mutex);
535
  else
536
    return 0;
537
}
538
 
539
static inline int
540
__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
541
{
542
  mutex->depth = 0;
543
  mutex->owner = (pthread_t) 0;
544
  return __gthrw_(pthread_mutex_init) (&mutex->actual, NULL);
545
}
546
 
547
static inline int
548
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
549
{
550
  if (__gthread_active_p ())
551
    {
552
      pthread_t me = __gthrw_(pthread_self) ();
553
 
554
      if (mutex->owner != me)
555
        {
556
          __gthrw_(pthread_mutex_lock) (&mutex->actual);
557
          mutex->owner = me;
558
        }
559
 
560
      mutex->depth++;
561
    }
562
  return 0;
563
}
564
 
565
static inline int
566
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
567
{
568
  if (__gthread_active_p ())
569
    {
570
      pthread_t me = __gthrw_(pthread_self) ();
571
 
572
      if (mutex->owner != me)
573
        {
574
          if (__gthrw_(pthread_mutex_trylock) (&mutex->actual))
575
            return 1;
576
          mutex->owner = me;
577
        }
578
 
579
      mutex->depth++;
580
    }
581
  return 0;
582
}
583
 
584
static inline int
585
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
586
{
587
  if (__gthread_active_p ())
588
    {
589
      if (--mutex->depth == 0)
590
        {
591
           mutex->owner = (pthread_t) 0;
592
           __gthrw_(pthread_mutex_unlock) (&mutex->actual);
593
        }
594
    }
595
  return 0;
596
}
597
 
598
#endif /* _LIBOBJC */
599
 
600
#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.