2 // posix-threads.h - Defines for using POSIX threads.
4 /* Copyright (C) 1998, 1999, 2001, 2003 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
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).
27 typedef struct _Jv_Thread_t
29 // Flag values are defined in implementation.
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.
48 typedef void _Jv_ThreadStartFunc (java::lang::Thread
*);
51 // Condition Variables used to implement wait/notify/sleep/interrupt.
54 // Linked list of Threads that are waiting to be notified.
57 } _Jv_ConditionVariable_t
;
61 // For compatibility, simplicity, and correctness, we do not use the native
62 // pthreads recursive mutex implementation, but simulate them instead.
64 // Mutex the thread holds the entire time this mutex is held.
65 pthread_mutex_t mutex
;
67 // Thread holding this mutex.
70 // Number of times mutex is held (lock depth). If 0, the lock is not held.
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
80 _Jv_MutexCheckMonitor (_Jv_Mutex_t
*mu
)
82 return (mu
->owner
!= pthread_self());
86 // Condition variables.
89 int _Jv_CondWait (_Jv_ConditionVariable_t
*cv
, _Jv_Mutex_t
*mu
,
90 jlong millis
, jint nanos
);
92 int _Jv_CondNotify (_Jv_ConditionVariable_t
*cv
, _Jv_Mutex_t
*mu
);
94 int _Jv_CondNotifyAll (_Jv_ConditionVariable_t
*cv
, _Jv_Mutex_t
*mu
);
97 _Jv_CondInit (_Jv_ConditionVariable_t
*cv
)
111 _Jv_MutexInit (_Jv_Mutex_t
*mu
)
113 # ifdef LOCK_DEBUG /* Assumes Linuxthreads */
114 pthread_mutexattr_t attr
;
115 pthread_mutexattr_init(&attr
);
116 pthread_mutexattr_settype(&attr
, PTHREAD_MUTEX_ERRORCHECK
);
117 pthread_mutex_init (&mu
->mutex
, &attr
);
119 pthread_mutex_init (&mu
->mutex
, 0);
127 _Jv_MutexLock (_Jv_Mutex_t
*mu
)
129 pthread_t self
= pthread_self ();
130 if (mu
->owner
== self
)
137 int result
= pthread_mutex_lock (&mu
->mutex
);
140 fprintf(stderr
, "Pthread_mutex_lock returned %d\n", result
);
144 pthread_mutex_lock (&mu
->mutex
);
153 _Jv_MutexUnlock (_Jv_Mutex_t
*mu
)
155 if (_Jv_MutexCheckMonitor (mu
))
158 fprintf(stderr
, "_Jv_MutexUnlock: Not owner\n");
170 int result
= pthread_mutex_unlock (&mu
->mutex
);
173 fprintf(stderr
, "Pthread_mutex_unlock returned %d\n", result
);
177 pthread_mutex_unlock (&mu
->mutex
);
183 #ifndef LINUX_THREADS
185 // pthread_mutex_destroy does nothing on Linux and it is a win to avoid
186 // defining this macro.
188 #define _Jv_HaveMutexDestroy
191 _Jv_MutexDestroy (_Jv_Mutex_t
*mu
)
193 pthread_mutex_destroy (&mu
->mutex
);
196 #endif /* LINUX_THREADS */
199 // Thread creation and manipulation.
202 void _Jv_InitThreads (void);
204 _Jv_Thread_t
*_Jv_ThreadInitData (java::lang::Thread
*thread
);
205 void _Jv_ThreadDestroyData (_Jv_Thread_t
*data
);
207 inline java::lang::Thread
*
208 _Jv_ThreadCurrent (void)
210 extern pthread_key_t _Jv_ThreadKey
;
211 return (java::lang::Thread
*) pthread_getspecific (_Jv_ThreadKey
);
214 #ifdef JV_HASH_SYNCHRONIZATION
215 // Should be specialized to just load the "current thread" register
216 // on platforms that support it. Speed is of the essence. The value
217 // of the descriptor is not, so long as there is a one-to-one correspondence
223 typedef size_t _Jv_ThreadId_t
;
225 register size_t _Jv_self
__asm__("r13");
226 // For linux_threads this is really a pointer to its thread data
227 // structure. We treat it as opaque. That should also work
228 // on other operating systems that follow the ABI standard.
230 // This should become the prototype for machines that maintain a thread
231 // pointer in a register.
232 inline _Jv_ThreadId_t
233 _Jv_ThreadSelf (void)
238 #define JV_SELF_DEFINED
240 #endif /* __ia64__ */
245 #include <machine/pal.h>
246 #define PAL_rduniq PAL_rdunique
247 #elif defined (__osf__)
248 #include <machine/pal.h>
253 typedef unsigned long _Jv_ThreadId_t
;
255 inline _Jv_ThreadId_t
256 _Jv_ThreadSelf (void)
258 register unsigned long id
__asm__("$0");
259 __asm__ ("call_pal %1" : "=r"(id
) : "i"(PAL_rduniq
));
263 #define JV_SELF_DEFINED
265 #endif /* __alpha__ */
267 #if defined(SLOW_PTHREAD_SELF)
269 #include "sysdep/locks.h"
271 typedef pthread_t _Jv_ThreadId_t
;
273 // E.g. on X86 Linux, pthread_self() is too slow for our purpose.
274 // Instead we maintain a cache based on the current sp value.
275 // This is similar to what's done for thread local allocation in the
276 // GC, only far simpler.
277 // This code should probably go away when Linux/X86 starts using a
278 // segment register to hold the thread id.
279 # define LOG_THREAD_SPACING 12
280 // If two thread pointer values are closer than
281 // 1 << LOG_THREAD_SPACING, we assume they belong
282 // to the same thread.
283 # define SELF_CACHE_SIZE 1024
284 # define SC_INDEX(sp) (((unsigned long)(sp) >> 19) & (SELF_CACHE_SIZE-1))
285 // Mapping from sp value to cache index.
286 // Note that this is not in any real sense a hash
287 // function, since we need to be able to clear
288 // all possibly matching slots on thread startup.
289 // Thus all entries that might correspond to
290 // a given thread are intentionally contiguous.
291 // Works well with anything that allocates at least
293 # define SC_CLEAR_MIN (-16) // When starting a new thread, we clear
294 # define SC_CLEAR_MAX 0 // all self cache entries between
295 // SC_INDEX(sp)+SC_CLEAR_MIN and
296 // SC_INDEX(sp)+SC_CLEAR_MAX to ensure
297 // we never see stale values. The
298 // current values assume a downward
299 // growing stack of size <= 7.5 MB.
300 # define BAD_HIGH_SP_VALUE ((size_t)(-1))
303 struct self_cache_entry
{
304 size_t high_sp_bits
; // sp value >> LOG_THREAD_SPACING
305 pthread_t self
; // Corresponding thread
308 void _Jv_Self_Cache_Init();
311 _Jv_ThreadSelf_out_of_line(volatile self_cache_entry
*sce
,
312 size_t high_sp_bits
);
314 inline _Jv_ThreadId_t
315 _Jv_ThreadSelf (void)
318 size_t sp
= (size_t)(&dummy
);
319 unsigned h
= SC_INDEX(sp
);
320 volatile self_cache_entry
*sce
= _Jv_self_cache
+ h
;
321 pthread_t candidate_self
= sce
-> self
; // Read must precede following one.
323 if (sce
-> high_sp_bits
== sp
>> LOG_THREAD_SPACING
)
325 // The sce -> self value we read must be valid. An intervening
326 // cache replacement by another thread would have first replaced
327 // high_sp_bits by something else, and it can't possibly change
328 // back without our intervention.
329 return candidate_self
;
332 return _Jv_ThreadSelf_out_of_line(sce
, sp
>> LOG_THREAD_SPACING
);
335 #define JV_SELF_DEFINED
337 #endif /* SLOW_PTHREAD_SELF */
339 #ifndef JV_SELF_DEFINED /* If all else fails, call pthread_self directly */
341 typedef pthread_t _Jv_ThreadId_t
;
343 inline _Jv_ThreadId_t
344 _Jv_ThreadSelf (void)
346 return pthread_self();
349 #endif /* !JV_SELF_DEFINED */
351 #endif /* JV_HASH_SYNCHRONIZATION */
353 inline _Jv_Thread_t
*
354 _Jv_ThreadCurrentData (void)
356 extern pthread_key_t _Jv_ThreadDataKey
;
357 return (_Jv_Thread_t
*) pthread_getspecific (_Jv_ThreadDataKey
);
361 _Jv_ThreadYield (void)
363 #ifdef HAVE_SCHED_YIELD
365 #endif /* HAVE_SCHED_YIELD */
368 void _Jv_ThreadRegister (_Jv_Thread_t
*data
);
369 void _Jv_ThreadUnRegister ();
371 void _Jv_ThreadSetPriority (_Jv_Thread_t
*data
, jint prio
);
373 void _Jv_ThreadStart (java::lang::Thread
*thread
, _Jv_Thread_t
*data
,
374 _Jv_ThreadStartFunc
*meth
);
376 void _Jv_ThreadWait (void);
378 void _Jv_ThreadInterrupt (_Jv_Thread_t
*data
);
380 #endif /* __JV_POSIX_THREADS__ */