2 // posix-threads.h - Defines for using POSIX threads.
4 /* Copyright (C) 1998, 1999 Cygnus Solutions
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
104 _Jv_PthreadCheckMonitor (_Jv_Mutex_t
*mu
)
106 pthread_mutex_t
*pmu
= _Jv_PthreadGetMutex (mu
);
107 // See if the mutex is locked by this thread.
108 if (pthread_mutex_trylock (pmu
))
110 #if defined (PTHREAD_MUTEX_HAVE_M_COUNT)
111 // On Linux we exploit knowledge of the implementation.
112 int r
= pmu
->m_count
== 1;
113 #elif defined (PTHREAD_MUTEX_HAVE___M_COUNT)
114 // In glibc 2.1, the first time the mutex is grabbed __m_count is
115 // set to 0 and __m_owner is set to pthread_self().
116 int r
= ! pmu
->__m_count
;
118 int r
= mu
->count
== 0;
120 pthread_mutex_unlock (pmu
);
125 // Condition variables.
129 _Jv_CondInit (_Jv_ConditionVariable_t
*cv
)
131 pthread_cond_init (cv
, 0);
134 #ifndef LINUX_THREADS
136 // pthread_cond_destroy does nothing on Linux and it is a win to avoid
137 // defining this macro.
139 #define _Jv_HaveCondDestroy
142 _Jv_CondDestroy (_Jv_ConditionVariable_t
*cv
)
144 pthread_cond_destroy (cv
);
147 #endif /* LINUX_THREADS */
149 int _Jv_CondWait (_Jv_ConditionVariable_t
*cv
, _Jv_Mutex_t
*mu
,
150 jlong millis
, jint nanos
);
153 _Jv_CondNotify (_Jv_ConditionVariable_t
*cv
, _Jv_Mutex_t
*mu
)
155 return _Jv_PthreadCheckMonitor (mu
) || pthread_cond_signal (cv
);
159 _Jv_CondNotifyAll (_Jv_ConditionVariable_t
*cv
, _Jv_Mutex_t
*mu
)
161 return _Jv_PthreadCheckMonitor (mu
) || pthread_cond_broadcast (cv
);
169 #ifdef RECURSIVE_MUTEX_IS_DEFAULT
171 _Jv_MutexInit (_Jv_Mutex_t
*mu
)
173 pthread_mutex_init (_Jv_PthreadGetMutex (mu
), NULL
);
174 #ifdef PTHREAD_MUTEX_IS_STRUCT
179 void _Jv_MutexInit (_Jv_Mutex_t
*mu
);
182 #ifndef LINUX_THREADS
184 // pthread_mutex_destroy does nothing on Linux and it is a win to avoid
185 // defining this macro.
187 #define _Jv_HaveMutexDestroy
189 #ifdef HAVE_RECURSIVE_MUTEX
192 _Jv_MutexDestroy (_Jv_Mutex_t
*mu
)
194 pthread_mutex_destroy (_Jv_PthreadGetMutex (mu
));
197 #else /* HAVE_RECURSIVE_MUTEX */
199 extern void _Jv_MutexDestroy (_Jv_Mutex_t
*mu
);
201 #endif /* HAVE_RECURSIVE_MUTEX */
202 #endif /* LINUX_THREADS */
204 #ifdef HAVE_RECURSIVE_MUTEX
207 _Jv_MutexLock (_Jv_Mutex_t
*mu
)
209 int r
= pthread_mutex_lock (_Jv_PthreadGetMutex (mu
));
210 #ifdef PTHREAD_MUTEX_IS_STRUCT
218 _Jv_MutexUnlock (_Jv_Mutex_t
*mu
)
220 int r
= pthread_mutex_unlock (_Jv_PthreadGetMutex (mu
));
221 #ifdef PTHREAD_MUTEX_IS_STRUCT
228 #else /* HAVE_RECURSIVE_MUTEX */
230 extern int _Jv_MutexLock (_Jv_Mutex_t
*mu
);
231 extern int _Jv_MutexUnlock (_Jv_Mutex_t
*mu
);
233 #endif /* HAVE_RECURSIVE_MUTEX */
237 // Thread creation and manipulation.
240 void _Jv_InitThreads (void);
242 void _Jv_ThreadInitData (_Jv_Thread_t
**data
, java::lang::Thread
*thread
);
244 inline java::lang::Thread
*
245 _Jv_ThreadCurrent (void)
247 extern pthread_key_t _Jv_ThreadKey
;
248 return (java::lang::Thread
*) pthread_getspecific (_Jv_ThreadKey
);
251 inline _Jv_Thread_t
*
252 _Jv_ThreadCurrentData (void)
254 extern pthread_key_t _Jv_ThreadDataKey
;
255 return (_Jv_Thread_t
*) pthread_getspecific (_Jv_ThreadDataKey
);
259 _Jv_ThreadYield (void)
261 #ifdef HAVE_SCHED_YIELD
263 #endif /* HAVE_SCHED_YIELD */
266 void _Jv_ThreadSetPriority (_Jv_Thread_t
*data
, jint prio
);
268 void _Jv_ThreadStart (java::lang::Thread
*thread
, _Jv_Thread_t
*data
,
269 _Jv_ThreadStartFunc
*meth
);
271 void _Jv_ThreadWait (void);
273 void _Jv_ThreadInterrupt (_Jv_Thread_t
*data
);
275 #endif /* __JV_POSIX_THREADS__ */