* libsupc++/eh_personality.cc: Wrap extern C function
[official-gcc.git] / libjava / include / posix-threads.h
blob8d69652e9e147c8c2e6e16f4373863dcd7a09f08
1 // -*- c++ -*-
2 // posix-threads.h - Defines for using POSIX threads.
4 /* Copyright (C) 1998, 1999, 2001, 2003, 2006 Free Software Foundation
6 This file is part of libgcj.
8 This software is copyrighted work licensed under the terms of the
9 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
10 details. */
12 #ifndef __JV_POSIX_THREADS__
13 #define __JV_POSIX_THREADS__
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).
20 #include <pthread.h>
21 #include <sched.h>
24 // Typedefs.
27 typedef struct _Jv_Thread_t
29 // Flag values are defined in implementation.
30 int flags;
32 // Actual thread id.
33 pthread_t thread;
35 // Java Thread object.
36 java::lang::Thread *thread_obj;
38 // Condition variable and corresponding mutex, used to implement the
39 // interruptable wait/notify mechanism.
40 pthread_cond_t wait_cond;
41 pthread_mutex_t wait_mutex;
43 // Next thread for Condition Variable wait-list chain.
44 _Jv_Thread_t *next;
46 } _Jv_Thread_t;
48 typedef void _Jv_ThreadStartFunc (java::lang::Thread *);
50 // Condition Variables used to implement wait/notify/sleep/interrupt.
51 typedef struct
53 // Linked list of Threads that are waiting to be notified.
54 _Jv_Thread_t *first;
56 } _Jv_ConditionVariable_t;
58 typedef struct
60 // For compatibility, simplicity, and correctness, we do not use the native
61 // pthreads recursive mutex implementation, but simulate them instead.
63 // Mutex the thread holds the entire time this mutex is held.
64 pthread_mutex_t mutex;
66 // Thread holding this mutex.
67 pthread_t owner;
69 // Number of times mutex is held (lock depth). If 0, the lock is not held.
70 int count;
71 } _Jv_Mutex_t;
73 // This is a convenience function used only by the pthreads thread
74 // implementation. This is slow, but that's too bad -- we need to do
75 // the checks for correctness. It might be nice to be able to compile
76 // this out. Returns 0 if the lock is held by the current thread, and
77 // 1 otherwise.
78 inline int
79 _Jv_MutexCheckMonitor (_Jv_Mutex_t *mu)
81 return (mu->owner != pthread_self());
84 // Type identifying a POSIX thread.
85 typedef pthread_t _Jv_ThreadDesc_t;
87 inline _Jv_ThreadDesc_t
88 _Jv_GetPlatformThreadID(_Jv_Thread_t *t)
90 return t->thread;
94 // Condition variables.
97 int _Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu,
98 jlong millis, jint nanos);
100 int _Jv_CondNotify (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu);
102 int _Jv_CondNotifyAll (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu);
104 inline void
105 _Jv_CondInit (_Jv_ConditionVariable_t *cv)
107 cv->first = 0;
111 // Mutexes.
114 #ifdef LOCK_DEBUG
115 # include <stdio.h>
116 #endif
118 inline void
119 _Jv_MutexInit (_Jv_Mutex_t *mu)
121 # ifdef LOCK_DEBUG /* Assumes Linuxthreads */
122 pthread_mutexattr_t attr;
123 pthread_mutexattr_init(&attr);
124 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
125 pthread_mutex_init (&mu->mutex, &attr);
126 # else
127 pthread_mutex_init (&mu->mutex, 0);
128 # endif
130 mu->count = 0;
131 mu->owner = 0;
134 inline int
135 _Jv_MutexLock (_Jv_Mutex_t *mu)
137 pthread_t self = pthread_self ();
138 if (mu->owner == self)
140 mu->count++;
142 else
144 # ifdef LOCK_DEBUG
145 int result = pthread_mutex_lock (&mu->mutex);
146 if (0 != result)
148 fprintf(stderr, "Pthread_mutex_lock returned %d\n", result);
149 for (;;) {}
151 # else
152 pthread_mutex_lock (&mu->mutex);
153 # endif
154 mu->count = 1;
155 mu->owner = self;
157 return 0;
160 inline int
161 _Jv_MutexUnlock (_Jv_Mutex_t *mu)
163 if (_Jv_MutexCheckMonitor (mu))
165 # ifdef LOCK_DEBUG
166 fprintf(stderr, "_Jv_MutexUnlock: Not owner\n");
167 for (;;) {}
168 # endif
169 return 1;
172 mu->count--;
174 if (mu->count == 0)
176 mu->owner = 0;
177 # ifdef LOCK_DEBUG
178 int result = pthread_mutex_unlock (&mu->mutex);
179 if (0 != result)
181 fprintf(stderr, "Pthread_mutex_unlock returned %d\n", result);
182 for (;;) {}
184 # else
185 pthread_mutex_unlock (&mu->mutex);
186 # endif
188 return 0;
191 #ifndef LINUX_THREADS
193 // pthread_mutex_destroy does nothing on Linux and it is a win to avoid
194 // defining this macro.
196 #define _Jv_HaveMutexDestroy
198 inline void
199 _Jv_MutexDestroy (_Jv_Mutex_t *mu)
201 pthread_mutex_destroy (&mu->mutex);
204 #endif /* LINUX_THREADS */
207 // Thread creation and manipulation.
210 void _Jv_InitThreads (void);
212 _Jv_Thread_t *_Jv_ThreadInitData (java::lang::Thread *thread);
213 void _Jv_ThreadDestroyData (_Jv_Thread_t *data);
215 inline java::lang::Thread *
216 _Jv_ThreadCurrent (void)
218 extern pthread_key_t _Jv_ThreadKey;
219 return (java::lang::Thread *) pthread_getspecific (_Jv_ThreadKey);
222 #ifdef JV_HASH_SYNCHRONIZATION
223 // Should be specialized to just load the "current thread" register
224 // on platforms that support it. Speed is of the essence. The value
225 // of the descriptor is not, so long as there is a one-to-one correspondence
226 // to threads.
229 #ifdef __ia64__
231 typedef size_t _Jv_ThreadId_t;
233 register size_t _Jv_self __asm__("r13");
234 // For linux_threads this is really a pointer to its thread data
235 // structure. We treat it as opaque. That should also work
236 // on other operating systems that follow the ABI standard.
238 // This should become the prototype for machines that maintain a thread
239 // pointer in a register.
240 inline _Jv_ThreadId_t
241 _Jv_ThreadSelf (void)
243 return _Jv_self;
246 #define JV_SELF_DEFINED
248 #endif /* __ia64__ */
250 #ifdef __alpha__
252 typedef void *_Jv_ThreadId_t;
254 inline _Jv_ThreadId_t
255 _Jv_ThreadSelf (void)
257 return __builtin_thread_pointer ();
260 #define JV_SELF_DEFINED
262 #endif /* __alpha__ */
264 #if defined(SLOW_PTHREAD_SELF)
266 #include "sysdep/locks.h"
268 typedef pthread_t _Jv_ThreadId_t;
270 // E.g. on X86 Linux, pthread_self() is too slow for our purpose.
271 // Instead we maintain a cache based on the current sp value.
272 // This is similar to what's done for thread local allocation in the
273 // GC, only far simpler.
274 // This code should probably go away when Linux/X86 starts using a
275 // segment register to hold the thread id.
276 # define LOG_THREAD_SPACING 12
277 // If two thread pointer values are closer than
278 // 1 << LOG_THREAD_SPACING, we assume they belong
279 // to the same thread.
280 # define SELF_CACHE_SIZE 1024
281 # define SC_INDEX(sp) (((unsigned long)(sp) >> 19) & (SELF_CACHE_SIZE-1))
282 // Mapping from sp value to cache index.
283 // Note that this is not in any real sense a hash
284 // function, since we need to be able to clear
285 // all possibly matching slots on thread startup.
286 // Thus all entries that might correspond to
287 // a given thread are intentionally contiguous.
288 // Works well with anything that allocates at least
289 // 512KB stacks.
290 # define SC_CLEAR_MIN (-16) // When starting a new thread, we clear
291 # define SC_CLEAR_MAX 0 // all self cache entries between
292 // SC_INDEX(sp)+SC_CLEAR_MIN and
293 // SC_INDEX(sp)+SC_CLEAR_MAX to ensure
294 // we never see stale values. The
295 // current values assume a downward
296 // growing stack of size <= 7.5 MB.
297 # define BAD_HIGH_SP_VALUE ((size_t)(-1))
299 extern volatile
300 struct self_cache_entry {
301 size_t high_sp_bits; // sp value >> LOG_THREAD_SPACING
302 pthread_t self; // Corresponding thread
303 } _Jv_self_cache[];
305 void _Jv_Self_Cache_Init();
307 _Jv_ThreadId_t
308 _Jv_ThreadSelf_out_of_line(volatile self_cache_entry *sce,
309 size_t high_sp_bits);
311 inline _Jv_ThreadId_t
312 _Jv_ThreadSelf (void)
314 int dummy;
315 size_t sp = (size_t)(&dummy);
316 unsigned h = SC_INDEX(sp);
317 volatile self_cache_entry *sce = _Jv_self_cache + h;
318 pthread_t candidate_self = sce -> self; // Read must precede following one.
319 read_barrier();
320 if (sce -> high_sp_bits == sp >> LOG_THREAD_SPACING)
322 // The sce -> self value we read must be valid. An intervening
323 // cache replacement by another thread would have first replaced
324 // high_sp_bits by something else, and it can't possibly change
325 // back without our intervention.
326 return candidate_self;
328 else
329 return _Jv_ThreadSelf_out_of_line(sce, sp >> LOG_THREAD_SPACING);
332 #define JV_SELF_DEFINED
334 #endif /* SLOW_PTHREAD_SELF */
336 #ifndef JV_SELF_DEFINED /* If all else fails, call pthread_self directly */
338 typedef pthread_t _Jv_ThreadId_t;
340 inline _Jv_ThreadId_t
341 _Jv_ThreadSelf (void)
343 return pthread_self();
346 #endif /* !JV_SELF_DEFINED */
348 #endif /* JV_HASH_SYNCHRONIZATION */
350 inline _Jv_Thread_t *
351 _Jv_ThreadCurrentData (void)
353 extern pthread_key_t _Jv_ThreadDataKey;
354 return (_Jv_Thread_t *) pthread_getspecific (_Jv_ThreadDataKey);
357 inline void
358 _Jv_ThreadYield (void)
360 #ifdef HAVE_SCHED_YIELD
361 sched_yield ();
362 #endif /* HAVE_SCHED_YIELD */
365 void _Jv_ThreadRegister (_Jv_Thread_t *data);
366 void _Jv_ThreadUnRegister ();
368 void _Jv_ThreadSetPriority (_Jv_Thread_t *data, jint prio);
370 void _Jv_ThreadStart (java::lang::Thread *thread, _Jv_Thread_t *data,
371 _Jv_ThreadStartFunc *meth);
373 void _Jv_ThreadWait (void);
375 void _Jv_ThreadInterrupt (_Jv_Thread_t *data);
377 // Increases a thread's suspend count. If the thread's previous
378 // suspend count was zero, i.e., it is not suspended, this function
379 // will suspend the thread. This function may be used to suspend
380 // any thread from any other thread (or suspend itself).
381 void _Jv_ThreadDebugSuspend (_Jv_Thread_t *data);
383 // Decreases a thread's suspend count. If the thread's new thread
384 // count is zero, the thread is resumed. This function may be used
385 // by any thread to resume any other thread.
386 void _Jv_ThreadDebugResume (_Jv_Thread_t *data);
388 // Get the suspend count for a thread
389 jint _Jv_ThreadDebugSuspendCount (_Jv_Thread_t *data);
391 #endif /* __JV_POSIX_THREADS__ */