2 // posix-threads.h - Defines for using POSIX threads.
4 /* Copyright (C) 1998, 1999 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).
23 #if defined (HAVE_PTHREAD_MUTEXATTR_SETTYPE) || defined (HAVE_PTHREAD_MUTEXATTR_SETKIND_NP)
24 # define HAVE_RECURSIVE_MUTEX 1
32 typedef pthread_cond_t _Jv_ConditionVariable_t;
34 #if defined (PTHREAD_MUTEX_HAVE_M_COUNT) || defined (PTHREAD_MUTEX_HAVE___M_COUNT)
36 // On Linux we use implementation details of mutexes in order to get
38 typedef pthread_mutex_t _Jv_Mutex_t;
40 #else /* LINUX_THREADS */
42 #define PTHREAD_MUTEX_IS_STRUCT
46 // Mutex used when locking this structure transiently.
47 pthread_mutex_t mutex;
48 #ifndef HAVE_RECURSIVE_MUTEX
49 // Some systems do not have recursive mutexes, so we must simulate
50 // them. Solaris is one such system.
52 // Mutex the thread holds the entire time this mutex is held. This
53 // is used to make condition variables work properly.
54 pthread_mutex_t mutex2;
55 // Condition variable used when waiting for this lock.
57 // Thread holding this mutex. If COUNT is 0, no thread is holding.
59 #endif /* HAVE_RECURSIVE_MUTEX */
61 // Number of times mutex is held. If 0, the lock is not held. We
62 // do this even if we have a native recursive mutex so that we can
63 // keep track of whether the lock is held; this lets us do error
64 // checking. FIXME it would be nice to optimize this; on some
65 // systems we could do so by relying on implementation details of
74 // Flag values are defined in implementation.
80 typedef void _Jv_ThreadStartFunc (java::lang::Thread *);
83 // This convenience function is used to return the POSIX mutex
84 // corresponding to our mutex.
85 inline pthread_mutex_t *
86 _Jv_PthreadGetMutex (_Jv_Mutex_t *mu)
88 #if ! defined (PTHREAD_MUTEX_IS_STRUCT)
90 #elif defined (HAVE_RECURSIVE_MUTEX)
99 // This is a convenience function used only by the pthreads thread
100 // implementation. This is slow, but that's too bad -- we need to do
101 // the checks for correctness. It might be nice to be able to compile
102 // this out. Returns 0 if the lock is held by the current thread, and
105 _Jv_PthreadCheckMonitor (_Jv_Mutex_t *mu)
107 pthread_mutex_t *pmu;
108 #ifdef HAVE_RECURSIVE_MUTEX
109 pmu = _Jv_PthreadGetMutex (mu);
110 // See if the mutex is locked by this thread.
111 if (pthread_mutex_trylock (pmu))
114 #if defined (PTHREAD_MUTEX_HAVE_M_COUNT)
115 // On Linux we exploit knowledge of the implementation.
116 int r = pmu->m_count == 1;
117 #elif defined (PTHREAD_MUTEX_HAVE___M_COUNT)
118 // In glibc 2.1, the first time the mutex is grabbed __m_count is
119 // set to 0 and __m_owner is set to pthread_self().
120 int r = ! pmu->__m_count;
122 int r = mu->count == 0;
125 #else /* HAVE_RECURSIVE_MUTEX */
126 // In this case we must lock our structure and then see if this
127 // thread owns the mutex.
129 if (pthread_mutex_lock (pmu))
132 int r = mu->thread != pthread_self () || mu->count == 0;
133 #endif /* HAVE_RECURSIVE_MUTEX */
135 pthread_mutex_unlock (pmu);
140 // Condition variables.
144 _Jv_CondInit (_Jv_ConditionVariable_t *cv)
146 pthread_cond_init (cv, 0);
149 #ifndef LINUX_THREADS
151 // pthread_cond_destroy does nothing on Linux and it is a win to avoid
152 // defining this macro.
154 #define _Jv_HaveCondDestroy
157 _Jv_CondDestroy (_Jv_ConditionVariable_t *cv)
159 pthread_cond_destroy (cv);
162 #endif /* LINUX_THREADS */
164 int _Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu,
165 jlong millis, jint nanos);
168 _Jv_CondNotify (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu)
170 return _Jv_PthreadCheckMonitor (mu) || pthread_cond_signal (cv);
174 _Jv_CondNotifyAll (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu)
176 return _Jv_PthreadCheckMonitor (mu) || pthread_cond_broadcast (cv);
184 #ifdef RECURSIVE_MUTEX_IS_DEFAULT
186 _Jv_MutexInit (_Jv_Mutex_t *mu)
188 pthread_mutex_init (_Jv_PthreadGetMutex (mu), NULL);
189 #ifdef PTHREAD_MUTEX_IS_STRUCT
194 void _Jv_MutexInit (_Jv_Mutex_t *mu);
197 #ifndef LINUX_THREADS
199 // pthread_mutex_destroy does nothing on Linux and it is a win to avoid
200 // defining this macro.
202 #define _Jv_HaveMutexDestroy
204 #ifdef HAVE_RECURSIVE_MUTEX
207 _Jv_MutexDestroy (_Jv_Mutex_t *mu)
209 pthread_mutex_destroy (_Jv_PthreadGetMutex (mu));
212 #else /* HAVE_RECURSIVE_MUTEX */
214 extern void _Jv_MutexDestroy (_Jv_Mutex_t *mu);
216 #endif /* HAVE_RECURSIVE_MUTEX */
217 #endif /* LINUX_THREADS */
219 #ifdef HAVE_RECURSIVE_MUTEX
222 _Jv_MutexLock (_Jv_Mutex_t *mu)
224 int r = pthread_mutex_lock (_Jv_PthreadGetMutex (mu));
225 #ifdef PTHREAD_MUTEX_IS_STRUCT
233 _Jv_MutexUnlock (_Jv_Mutex_t *mu)
235 int r = pthread_mutex_unlock (_Jv_PthreadGetMutex (mu));
236 #ifdef PTHREAD_MUTEX_IS_STRUCT
243 #else /* HAVE_RECURSIVE_MUTEX */
245 extern int _Jv_MutexLock (_Jv_Mutex_t *mu);
246 extern int _Jv_MutexUnlock (_Jv_Mutex_t *mu);
248 #endif /* HAVE_RECURSIVE_MUTEX */
252 // Thread creation and manipulation.
255 void _Jv_InitThreads (void);
257 void _Jv_ThreadInitData (_Jv_Thread_t **data, java::lang::Thread *thread);
259 inline java::lang::Thread *
260 _Jv_ThreadCurrent (void)
262 extern pthread_key_t _Jv_ThreadKey;
263 return (java::lang::Thread *) pthread_getspecific (_Jv_ThreadKey);
266 inline _Jv_Thread_t *
267 _Jv_ThreadCurrentData (void)
269 extern pthread_key_t _Jv_ThreadDataKey;
270 return (_Jv_Thread_t *) pthread_getspecific (_Jv_ThreadDataKey);
274 _Jv_ThreadYield (void)
276 #ifdef HAVE_SCHED_YIELD
278 #endif /* HAVE_SCHED_YIELD */
281 void _Jv_ThreadSetPriority (_Jv_Thread_t *data, jint prio);
283 void _Jv_ThreadStart (java::lang::Thread *thread, _Jv_Thread_t *data,
284 _Jv_ThreadStartFunc *meth);
286 void _Jv_ThreadWait (void);
288 void _Jv_ThreadInterrupt (_Jv_Thread_t *data);
290 #endif /* __JV_POSIX_THREADS__ */