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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [gthr-solaris.h] - Blame information for rev 826

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 280 jeremybenn
/* Threads compatibility routines for libgcc2 and libobjc.  */
2
/* Compile this one with gcc.  */
3
/* Copyright (C) 1997, 1999, 2000, 2004, 2005, 2006, 2008, 2009
4
   Free Software Foundation, Inc.
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify it under
9
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 3, or (at your option) any later
11
version.
12
 
13
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14
WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
for more details.
17
 
18
Under Section 7 of GPL version 3, you are granted additional
19
permissions described in the GCC Runtime Library Exception, version
20
3.1, as published by the Free Software Foundation.
21
 
22
You should have received a copy of the GNU General Public License and
23
a copy of the GCC Runtime Library Exception along with this program;
24
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
25
<http://www.gnu.org/licenses/>.  */
26
 
27
#ifndef GCC_GTHR_SOLARIS_H
28
#define GCC_GTHR_SOLARIS_H
29
 
30
/* Solaris threads as found in Solaris 2.[456].
31
   Actually these are Unix International (UI) threads, but I don't
32
   know if anyone else implements these.  */
33
 
34
#define __GTHREADS 1
35
 
36
#include <thread.h>
37
#include <errno.h>
38
 
39
#ifdef __cplusplus
40
#define UNUSED(x)
41
#else
42
#define UNUSED(x) x __attribute__((unused))
43
#endif
44
 
45
typedef thread_key_t __gthread_key_t;
46
typedef struct {
47
  mutex_t mutex;
48
  int once;
49
} __gthread_once_t;
50
typedef mutex_t __gthread_mutex_t;
51
 
52
typedef struct {
53
  long depth;
54
  thread_t owner;
55
  mutex_t actual;
56
} __gthread_recursive_mutex_t;
57
 
58
#define __GTHREAD_ONCE_INIT { DEFAULTMUTEX, 0 }
59
#define __GTHREAD_MUTEX_INIT DEFAULTMUTEX
60
#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
61
 
62
#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
63
# define __gthrw(name) \
64
  static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name)));
65
# define __gthrw_(name) __gthrw_ ## name
66
#else
67
# define __gthrw(name)
68
# define __gthrw_(name) name
69
#endif
70
 
71
__gthrw(thr_keycreate)
72
__gthrw(thr_getspecific)
73
__gthrw(thr_setspecific)
74
__gthrw(thr_create)
75
__gthrw(thr_self)
76
 
77
__gthrw(mutex_init)
78
__gthrw(mutex_destroy)
79
__gthrw(mutex_lock)
80
__gthrw(mutex_trylock)
81
__gthrw(mutex_unlock)
82
 
83
#ifdef _LIBOBJC
84
__gthrw(thr_exit)
85
__gthrw(thr_getprio)
86
__gthrw(thr_setprio)
87
__gthrw(thr_yield)
88
 
89
__gthrw(cond_init)
90
__gthrw(cond_destroy)
91
__gthrw(cond_wait)
92
__gthrw(cond_broadcast)
93
__gthrw(cond_signal)
94
 
95
#endif
96
 
97
#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
98
 
99
/* This will not actually work in Solaris 2.5, since libc contains
100
   dummy symbols of all thr_* routines.  */
101
 
102
static inline int
103
__gthread_active_p (void)
104
{
105
  static void *const __gthread_active_ptr
106
    = __extension__ (void *) &__gthrw_(thr_create);
107
  return __gthread_active_ptr != 0;
108
}
109
 
110
#else /* not SUPPORTS_WEAK */
111
 
112
static inline int
113
__gthread_active_p (void)
114
{
115
  return 1;
116
}
117
 
118
#endif /* SUPPORTS_WEAK */
119
 
120
#ifdef _LIBOBJC
121
 
122
/* Key structure for maintaining thread specific storage */
123
static thread_key_t _objc_thread_storage;
124
 
125
/* Thread local storage for a single thread */
126
static void *thread_local_storage = NULL;
127
 
128
/* Backend initialization functions */
129
 
130
/* Initialize the threads subsystem.  */
131
static inline int
132
__gthread_objc_init_thread_system (void)
133
{
134
  /* Initialize the thread storage key.  */
135
  if (__gthread_active_p ()
136
      && __gthrw_(thr_keycreate) (&_objc_thread_storage, NULL) == 0)
137
    return 0;
138
 
139
  return -1;
140
}
141
 
142
/* Close the threads subsystem.  */
143
static inline int
144
__gthread_objc_close_thread_system (void)
145
{
146
  if (__gthread_active_p ())
147
    return 0;
148
  else
149
    return -1;
150
}
151
 
152
/* Backend thread functions */
153
 
154
/* Create a new thread of execution.  */
155
static inline objc_thread_t
156
__gthread_objc_thread_detach (void (*func)(void *), void *arg)
157
{
158
  objc_thread_t thread_id;
159
  thread_t new_thread_id = 0;
160
 
161
  if (!__gthread_active_p ())
162
    return NULL;
163
 
164
  if (__gthrw_(thr_create) (NULL, 0, (void *) func, arg,
165
                  THR_DETACHED | THR_NEW_LWP,
166
                  &new_thread_id) == 0)
167
    thread_id = *(objc_thread_t *) &new_thread_id;
168
  else
169
    thread_id = NULL;
170
 
171
  return thread_id;
172
}
173
 
174
/* Set the current thread's priority.  */
175
static inline int
176
__gthread_objc_thread_set_priority (int priority)
177
{
178
  int sys_priority = 0;
179
 
180
  if (!__gthread_active_p ())
181
    return -1;
182
 
183
  switch (priority)
184
    {
185
    case OBJC_THREAD_INTERACTIVE_PRIORITY:
186
      sys_priority = 300;
187
      break;
188
    default:
189
    case OBJC_THREAD_BACKGROUND_PRIORITY:
190
      sys_priority = 200;
191
      break;
192
    case OBJC_THREAD_LOW_PRIORITY:
193
      sys_priority = 1000;
194
      break;
195
    }
196
 
197
  /* Change priority */
198
  if (__gthrw_(thr_setprio) (__gthrw_(thr_self) (), sys_priority) == 0)
199
    return 0;
200
  else
201
    return -1;
202
}
203
 
204
/* Return the current thread's priority.  */
205
static inline int
206
__gthread_objc_thread_get_priority (void)
207
{
208
  int sys_priority;
209
 
210
  if (!__gthread_active_p ())
211
    return OBJC_THREAD_INTERACTIVE_PRIORITY;
212
 
213
  if (__gthrw_(thr_getprio) (__gthrw_(thr_self) (), &sys_priority) == 0)
214
    {
215
      if (sys_priority >= 250)
216
        return OBJC_THREAD_INTERACTIVE_PRIORITY;
217
      else if (sys_priority >= 150)
218
        return OBJC_THREAD_BACKGROUND_PRIORITY;
219
      return OBJC_THREAD_LOW_PRIORITY;
220
    }
221
 
222
  /* Couldn't get priority.  */
223
  return -1;
224
}
225
 
226
/* Yield our process time to another thread.  */
227
static inline void
228
__gthread_objc_thread_yield (void)
229
{
230
  if (__gthread_active_p ())
231
    __gthrw_(thr_yield) ();
232
}
233
 
234
/* Terminate the current thread.  */
235
static inline int
236
__gthread_objc_thread_exit (void)
237
{
238
  if (__gthread_active_p ())
239
    /* exit the thread */
240
    __gthrw_(thr_exit) (&__objc_thread_exit_status);
241
 
242
  /* Failed if we reached here */
243
  return -1;
244
}
245
 
246
/* Returns an integer value which uniquely describes a thread.  */
247
static inline objc_thread_t
248
__gthread_objc_thread_id (void)
249
{
250
  if (__gthread_active_p ())
251
    return (objc_thread_t) __gthrw_(thr_self) ();
252
  else
253
    return (objc_thread_t) 1;
254
}
255
 
256
/* Sets the thread's local storage pointer.  */
257
static inline int
258
__gthread_objc_thread_set_data (void *value)
259
{
260
  if (__gthread_active_p ())
261
    {
262
      if (__gthrw_(thr_setspecific) (_objc_thread_storage, value) == 0)
263
        return 0;
264
      else
265
        return -1;
266
    }
267
  else
268
    {
269
      thread_local_storage = value;
270
      return 0;
271
    }
272
}
273
 
274
/* Returns the thread's local storage pointer.  */
275
static inline void *
276
__gthread_objc_thread_get_data (void)
277
{
278
  void *value = NULL;
279
 
280
  if (__gthread_active_p ())
281
    {
282
      if (__gthrw_(thr_getspecific) (_objc_thread_storage, &value) == 0)
283
        return value;
284
      else
285
        return NULL;
286
    }
287
  else
288
    return thread_local_storage;
289
}
290
 
291
/* Backend mutex functions */
292
 
293
/* Allocate a mutex.  */
294
static inline int
295
__gthread_objc_mutex_allocate (objc_mutex_t mutex)
296
{
297
  if (__gthread_active_p ()
298
      && __gthrw_(mutex_init) ((mutex_t *) (&(mutex->backend)), USYNC_THREAD, 0))
299
    return -1;
300
 
301
  return 0;
302
}
303
 
304
/* Deallocate a mutex.  */
305
static inline int
306
__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
307
{
308
  if (__gthread_active_p ())
309
    __gthrw_(mutex_destroy) ((mutex_t *) (&(mutex->backend)));
310
 
311
  return 0;
312
}
313
 
314
/* Grab a lock on a mutex.  */
315
static inline int
316
__gthread_objc_mutex_lock (objc_mutex_t mutex)
317
{
318
  if (__gthread_active_p ()
319
      && __gthrw_(mutex_lock) ((mutex_t *) (&(mutex->backend))) != 0)
320
    return -1;
321
 
322
  return 0;
323
}
324
 
325
/* Try to grab a lock on a mutex.  */
326
static inline int
327
__gthread_objc_mutex_trylock (objc_mutex_t mutex)
328
{
329
  if (__gthread_active_p ()
330
      && __gthrw_(mutex_trylock) ((mutex_t *) (&(mutex->backend))) != 0)
331
    return -1;
332
 
333
  return 0;
334
}
335
 
336
/* Unlock the mutex */
337
static inline int
338
__gthread_objc_mutex_unlock (objc_mutex_t mutex)
339
{
340
  if (__gthread_active_p ()
341
      && __gthrw_(mutex_unlock) ((mutex_t *) (&(mutex->backend))) != 0)
342
    return -1;
343
 
344
  return 0;
345
}
346
 
347
/* Backend condition mutex functions */
348
 
349
/* Allocate a condition.  */
350
static inline int
351
__gthread_objc_condition_allocate (objc_condition_t condition)
352
{
353
  if (__gthread_active_p ())
354
    return __gthrw_(cond_init) ((cond_t *) (&(condition->backend)), USYNC_THREAD,
355
                      NULL);
356
  else
357
    return 0;
358
}
359
 
360
/* Deallocate a condition.  */
361
static inline int
362
__gthread_objc_condition_deallocate (objc_condition_t condition)
363
{
364
  if (__gthread_active_p ())
365
    return __gthrw_(cond_destroy) ((cond_t *) (&(condition->backend)));
366
  else
367
    return 0;
368
}
369
 
370
/* Wait on the condition */
371
static inline int
372
__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
373
{
374
  if (__gthread_active_p ())
375
    return __gthrw_(cond_wait) ((cond_t *) (&(condition->backend)),
376
                      (mutex_t *) (&(mutex->backend)));
377
  else
378
    return 0;
379
}
380
 
381
/* Wake up all threads waiting on this condition.  */
382
static inline int
383
__gthread_objc_condition_broadcast (objc_condition_t condition)
384
{
385
  if (__gthread_active_p ())
386
    return __gthrw_(cond_broadcast) ((cond_t *) (&(condition->backend)));
387
  else
388
    return 0;
389
}
390
 
391
/* Wake up one thread waiting on this condition.  */
392
static inline int
393
__gthread_objc_condition_signal (objc_condition_t condition)
394
{
395
  if (__gthread_active_p ())
396
    return __gthrw_(cond_signal) ((cond_t *) (&(condition->backend)));
397
  else
398
    return 0;
399
}
400
 
401
#else /* _LIBOBJC */
402
 
403
static inline int
404
__gthread_once (__gthread_once_t *__once, void (*__func) (void))
405
{
406
  if (! __gthread_active_p ())
407
    return -1;
408
 
409
  if (__once == 0 || __func == 0)
410
    return EINVAL;
411
 
412
  if (__once->once == 0)
413
    {
414
      int __status = __gthrw_(mutex_lock) (&__once->mutex);
415
      if (__status != 0)
416
        return __status;
417
      if (__once->once == 0)
418
        {
419
          (*__func) ();
420
          __once->once++;
421
        }
422
      __gthrw_(mutex_unlock) (&__once->mutex);
423
    }
424
  return 0;
425
}
426
 
427
static inline int
428
__gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
429
{
430
  /* Solaris 2.5 contains thr_* routines no-op in libc, so test if we actually
431
     got a reasonable key value, and if not, fail.  */
432
  *__key = (__gthread_key_t)-1;
433
  if (__gthrw_(thr_keycreate) (__key, __dtor) != 0
434
      || *__key == (__gthread_key_t)-1)
435
    return -1;
436
  else
437
    return 0;
438
}
439
 
440
static inline int
441
__gthread_key_delete (__gthread_key_t UNUSED (__key))
442
{
443
  /* Not possible.  */
444
  return -1;
445
}
446
 
447
static inline void *
448
__gthread_getspecific (__gthread_key_t __key)
449
{
450
  void *__ptr;
451
  if (__gthrw_(thr_getspecific) (__key, &__ptr) == 0)
452
    return __ptr;
453
  else
454
    return 0;
455
}
456
 
457
static inline int
458
__gthread_setspecific (__gthread_key_t __key, const void *__ptr)
459
{
460
  return __gthrw_(thr_setspecific) (__key, (void *) __ptr);
461
}
462
 
463
static inline int
464
__gthread_mutex_destroy (__gthread_mutex_t *__mutex)
465
{
466
  if (__gthread_active_p ())
467
    return __gthrw_(mutex_destroy) (__mutex);
468
  else
469
    return 0;
470
}
471
 
472
static inline int
473
__gthread_mutex_lock (__gthread_mutex_t *__mutex)
474
{
475
  if (__gthread_active_p ())
476
    return __gthrw_(mutex_lock) (__mutex);
477
  else
478
    return 0;
479
}
480
 
481
static inline int
482
__gthread_mutex_trylock (__gthread_mutex_t *__mutex)
483
{
484
  if (__gthread_active_p ())
485
    return __gthrw_(mutex_trylock) (__mutex);
486
  else
487
    return 0;
488
}
489
 
490
static inline int
491
__gthread_mutex_unlock (__gthread_mutex_t *__mutex)
492
{
493
  if (__gthread_active_p ())
494
    return __gthrw_(mutex_unlock) (__mutex);
495
  else
496
    return 0;
497
}
498
 
499
static inline int
500
__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
501
{
502
  __mutex->depth = 0;
503
  __mutex->owner = (thread_t) 0;
504
  return __gthrw_(mutex_init) (&__mutex->actual, USYNC_THREAD, 0);
505
}
506
 
507
static inline int
508
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
509
{
510
  if (__gthread_active_p ())
511
    {
512
      thread_t __me = __gthrw_(thr_self) ();
513
 
514
      if (__mutex->owner != __me)
515
        {
516
          __gthrw_(mutex_lock) (&__mutex->actual);
517
          __mutex->owner = __me;
518
        }
519
 
520
      __mutex->depth++;
521
    }
522
  return 0;
523
}
524
 
525
static inline int
526
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
527
{
528
  if (__gthread_active_p ())
529
    {
530
      thread_t __me = __gthrw_(thr_self) ();
531
 
532
      if (__mutex->owner != __me)
533
        {
534
          if (__gthrw_(mutex_trylock) (&__mutex->actual))
535
            return 1;
536
          __mutex->owner = __me;
537
        }
538
 
539
      __mutex->depth++;
540
    }
541
  return 0;
542
}
543
 
544
static inline int
545
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
546
{
547
  if (__gthread_active_p ())
548
    {
549
      if (--__mutex->depth == 0)
550
        {
551
           __mutex->owner = (thread_t) 0;
552
           __gthrw_(mutex_unlock) (&__mutex->actual);
553
        }
554
    }
555
  return 0;
556
}
557
 
558
#endif /* _LIBOBJC */
559
 
560
#undef UNUSED
561
 
562
#endif /* ! GCC_GTHR_SOLARIS_H */

powered by: WebSVN 2.1.0

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