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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [include/] [posix-threads.h] - Blame information for rev 758

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 757 jeremybenn
// -*- c++ -*-
2
// posix-threads.h - Defines for using POSIX threads.
3
 
4
/* Copyright (C) 1998, 1999, 2001, 2003, 2006  Free Software Foundation
5
 
6
   This file is part of libgcj.
7
 
8
This software is copyrighted work licensed under the terms of the
9
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
10
details.  */
11
 
12
#ifndef __JV_POSIX_THREADS__
13
#define __JV_POSIX_THREADS__
14
 
15
// NOTE: This file may only reference those pthread functions which
16
// are known not to be overridden by the Boehm GC.  If in doubt, scan
17
// boehm-gc/gc.h.  This is yucky but lets us avoid including gc.h
18
// everywhere (which would be truly yucky).
19
 
20
#include <pthread.h>
21
#include <sched.h>
22
#include <sysdep/locks.h>
23
 
24
//
25
// Typedefs.
26
//
27
 
28
typedef struct _Jv_Thread_t
29
{
30
  // Flag values are defined in implementation.
31
  int flags;
32
 
33
  // Actual thread id.
34
  pthread_t thread;
35
 
36
  // Java Thread object.
37
  java::lang::Thread *thread_obj;
38
 
39
  // Condition variable and corresponding mutex, used to implement the
40
  // interruptable wait/notify mechanism.
41
  pthread_cond_t wait_cond;
42
  pthread_mutex_t wait_mutex;
43
 
44
  // Next thread for Condition Variable wait-list chain.
45
  _Jv_Thread_t *next;
46
 
47
} _Jv_Thread_t;
48
 
49
typedef void _Jv_ThreadStartFunc (java::lang::Thread *);
50
 
51
// Condition Variables used to implement wait/notify/sleep/interrupt.
52
typedef struct
53
{
54
  // Linked list of Threads that are waiting to be notified.
55
  _Jv_Thread_t *first;
56
 
57
} _Jv_ConditionVariable_t;
58
 
59
typedef struct
60
{
61
  // For compatibility, simplicity, and correctness, we do not use the native
62
  // pthreads recursive mutex implementation, but simulate them instead.
63
 
64
  // Mutex the thread holds the entire time this mutex is held. 
65
  pthread_mutex_t mutex;
66
 
67
  // Thread holding this mutex.
68
  pthread_t owner;
69
 
70
  // Number of times mutex is held (lock depth).  If 0, the lock is not held.
71
  int count;
72
} _Jv_Mutex_t;
73
 
74
// This is a convenience function used only by the pthreads thread
75
// implementation.  This is slow, but that's too bad -- we need to do
76
// the checks for correctness.  It might be nice to be able to compile
77
// this out.  Returns 0 if the lock is held by the current thread, and
78
// 1 otherwise.
79
inline int
80
_Jv_MutexCheckMonitor (_Jv_Mutex_t *mu)
81
{
82
  return (mu->owner != pthread_self());
83
}
84
 
85
// Type identifying a POSIX thread.
86
typedef pthread_t _Jv_ThreadDesc_t;
87
 
88
inline _Jv_ThreadDesc_t
89
_Jv_GetPlatformThreadID(_Jv_Thread_t *t)
90
{
91
  return t->thread;
92
}
93
 
94
//
95
// Signal helpers.
96
//
97
 
98
void _Jv_BlockSigchld();
99
void _Jv_UnBlockSigchld();
100
 
101
 
102
//
103
// Condition variables.
104
//
105
 
106
int _Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu,
107
                  jlong millis, jint nanos);
108
 
109
int _Jv_CondNotify (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu);
110
 
111
int _Jv_CondNotifyAll (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu);
112
 
113
inline void
114
_Jv_CondInit (_Jv_ConditionVariable_t *cv)
115
{
116
  cv->first = 0;
117
}
118
 
119
//
120
// Mutexes.
121
//
122
 
123
#ifdef LOCK_DEBUG
124
# include <stdio.h>
125
#endif
126
 
127
inline void
128
_Jv_MutexInit (_Jv_Mutex_t *mu)
129
{
130
# ifdef LOCK_DEBUG /* Assumes Linuxthreads */
131
  pthread_mutexattr_t attr;
132
  pthread_mutexattr_init(&attr);
133
  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
134
  pthread_mutex_init (&mu->mutex, &attr);
135
# else
136
  pthread_mutex_init (&mu->mutex, 0);
137
# endif
138
 
139
  mu->count = 0;
140
  mu->owner = 0;
141
}
142
 
143
extern int _Jv_MutexLock (_Jv_Mutex_t *);
144
 
145
inline int
146
_Jv_MutexUnlock (_Jv_Mutex_t *mu)
147
{
148
  if (_Jv_MutexCheckMonitor (mu))
149
    {
150
#     ifdef LOCK_DEBUG
151
        fprintf(stderr, "_Jv_MutexUnlock: Not owner\n");
152
        for (;;) {}
153
#     endif
154
      return 1;
155
    }
156
 
157
  mu->count--;
158
 
159
  if (mu->count == 0)
160
    {
161
      mu->owner = 0;
162
#     ifdef LOCK_DEBUG
163
        int result = pthread_mutex_unlock (&mu->mutex);
164
        if (0 != result)
165
          {
166
            fprintf(stderr, "Pthread_mutex_unlock returned %d\n", result);
167
            for (;;) {}
168
          }
169
#     else
170
        pthread_mutex_unlock (&mu->mutex);
171
#     endif
172
    }
173
  return 0;
174
}
175
 
176
#ifndef LINUX_THREADS
177
 
178
// pthread_mutex_destroy does nothing on Linux and it is a win to avoid
179
// defining this macro.
180
 
181
#define _Jv_HaveMutexDestroy
182
 
183
inline void
184
_Jv_MutexDestroy (_Jv_Mutex_t *mu)
185
{
186
  pthread_mutex_destroy (&mu->mutex);
187
}
188
 
189
#endif /* LINUX_THREADS */
190
 
191
//
192
// Thread creation and manipulation.
193
//
194
 
195
void _Jv_InitThreads (void);
196
 
197
_Jv_Thread_t *_Jv_ThreadInitData (java::lang::Thread *thread);
198
void _Jv_ThreadDestroyData (_Jv_Thread_t *data);
199
 
200
inline java::lang::Thread *
201
_Jv_ThreadCurrent (void)
202
{
203
  extern pthread_key_t _Jv_ThreadKey;
204
  return (java::lang::Thread *) pthread_getspecific (_Jv_ThreadKey);
205
}
206
 
207
#ifdef JV_HASH_SYNCHRONIZATION
208
// Should be specialized to just load the "current thread" register
209
// on platforms that support it.   Speed is of the essence.  The value
210
// of the descriptor is not, so long as there is a one-to-one correspondence
211
// to threads.
212
 
213
 
214
#ifdef __ia64__
215
 
216
typedef size_t _Jv_ThreadId_t;
217
 
218
register size_t _Jv_self __asm__("r13");
219
        // For linux_threads this is really a pointer to its thread data
220
        // structure.  We treat it as opaque.  That should also work
221
        // on other operating systems that follow the ABI standard.
222
 
223
// This should become the prototype for machines that maintain a thread
224
// pointer in a register.
225
inline _Jv_ThreadId_t
226
_Jv_ThreadSelf (void)
227
{
228
  return _Jv_self;
229
}
230
 
231
#define JV_SELF_DEFINED
232
 
233
#endif /* __ia64__ */
234
 
235
#ifdef __alpha__
236
 
237
typedef void *_Jv_ThreadId_t;
238
 
239
inline _Jv_ThreadId_t
240
_Jv_ThreadSelf (void)
241
{
242
  return __builtin_thread_pointer ();
243
}
244
 
245
#define JV_SELF_DEFINED
246
 
247
#endif /* __alpha__ */
248
 
249
#if defined(SLOW_PTHREAD_SELF)
250
 
251
#include "sysdep/locks.h"
252
 
253
typedef pthread_t _Jv_ThreadId_t;
254
 
255
// E.g. on X86 Linux, pthread_self() is too slow for our purpose.
256
// Instead we maintain a cache based on the current sp value.
257
// This is similar to what's done for thread local allocation in the
258
// GC, only far simpler.
259
// This code should probably go away when Linux/X86 starts using a
260
// segment register to hold the thread id.
261
# define LOG_THREAD_SPACING 12
262
                        // If two thread pointer values are closer than
263
                        // 1 << LOG_THREAD_SPACING, we assume they belong
264
                        // to the same thread.
265
# define SELF_CACHE_SIZE 1024
266
# define SC_INDEX(sp) (((unsigned long)(sp) >> 19) & (SELF_CACHE_SIZE-1))
267
                        // Mapping from sp value to cache index.
268
                        // Note that this is not in any real sense a hash
269
                        // function, since we need to be able to clear
270
                        // all possibly matching slots on thread startup.
271
                        // Thus all entries that might correspond to
272
                        // a given thread are intentionally contiguous.
273
                        // Works well with anything that allocates at least
274
                        // 512KB stacks.
275
# define SC_CLEAR_MIN (-16)     // When starting a new thread, we clear
276
# define SC_CLEAR_MAX 0         // all self cache entries between
277
                                // SC_INDEX(sp)+SC_CLEAR_MIN and
278
                                // SC_INDEX(sp)+SC_CLEAR_MAX to ensure
279
                                // we never see stale values.  The
280
                                // current values assume a downward
281
                                // growing stack of size <= 7.5 MB.
282
# define BAD_HIGH_SP_VALUE ((size_t)(-1))
283
 
284
extern volatile
285
struct self_cache_entry {
286
  size_t high_sp_bits;  // sp value >> LOG_THREAD_SPACING
287
  pthread_t self;       // Corresponding thread
288
} _Jv_self_cache[];
289
 
290
void _Jv_Self_Cache_Init();
291
 
292
_Jv_ThreadId_t
293
_Jv_ThreadSelf_out_of_line(volatile self_cache_entry *sce,
294
                           size_t high_sp_bits);
295
 
296
inline _Jv_ThreadId_t
297
_Jv_ThreadSelf (void)
298
{
299
  int dummy;
300
  size_t sp = (size_t)(&dummy);
301
  unsigned h = SC_INDEX(sp);
302
  volatile self_cache_entry *sce = _Jv_self_cache + h;
303
  pthread_t candidate_self = sce -> self;  // Read must precede following one.
304
  read_barrier();
305
  if (sce -> high_sp_bits == sp >> LOG_THREAD_SPACING)
306
    {
307
      // The sce -> self value we read must be valid.  An intervening
308
      // cache replacement by another thread would have first replaced
309
      // high_sp_bits by something else, and it can't possibly change
310
      // back without our intervention.
311
      return candidate_self;
312
    }
313
  else
314
    return _Jv_ThreadSelf_out_of_line(sce, sp >> LOG_THREAD_SPACING);
315
}
316
 
317
#define JV_SELF_DEFINED
318
 
319
#endif /* SLOW_PTHREAD_SELF */
320
 
321
#ifndef JV_SELF_DEFINED /* If all else fails, call pthread_self directly */
322
 
323
typedef pthread_t _Jv_ThreadId_t;
324
 
325
inline _Jv_ThreadId_t
326
_Jv_ThreadSelf (void)
327
{
328
  return pthread_self();
329
}
330
 
331
#endif /* !JV_SELF_DEFINED */
332
 
333
#endif /* JV_HASH_SYNCHRONIZATION */
334
 
335
inline _Jv_Thread_t *
336
_Jv_ThreadCurrentData (void)
337
{
338
  extern pthread_key_t _Jv_ThreadDataKey;
339
  return (_Jv_Thread_t *) pthread_getspecific (_Jv_ThreadDataKey);
340
}
341
 
342
inline void
343
_Jv_ThreadYield (void)
344
{
345
#ifdef HAVE_SCHED_YIELD
346
  sched_yield ();
347
#endif /* HAVE_SCHED_YIELD */
348
}
349
 
350
void _Jv_ThreadRegister (_Jv_Thread_t *data);
351
void _Jv_ThreadUnRegister ();
352
 
353
void _Jv_ThreadSetPriority (_Jv_Thread_t *data, jint prio);
354
 
355
void _Jv_ThreadStart (java::lang::Thread *thread, _Jv_Thread_t *data,
356
                      _Jv_ThreadStartFunc *meth);
357
 
358
void _Jv_ThreadWait (void);
359
 
360
void _Jv_ThreadInterrupt (_Jv_Thread_t *data);
361
 
362
// park() / unpark() support
363
 
364
struct ParkHelper
365
{
366
  volatile obj_addr_t permit;
367
  pthread_mutex_t mutex;
368
  pthread_cond_t cond;
369
 
370
  void init ();
371
  void deactivate ();
372
  void destroy ();
373
  void park (jboolean isAbsolute, jlong time);
374
  void unpark ();
375
};
376
 
377
inline void
378
ParkHelper::destroy ()
379
{
380
  pthread_mutex_destroy (&mutex);
381
  pthread_cond_destroy (&cond);
382
}
383
 
384
#endif /* __JV_POSIX_THREADS__ */

powered by: WebSVN 2.1.0

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