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

Subversion Repositories openrisc

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