OSDN Git Service

* include/quick-threads.h (_Jv_ThreadCancel): Removed.
[pf3gnuchains/gcc-fork.git] / libjava / include / posix-threads.h
1 // -*- c++ -*-
2 // posix-threads.h - Defines for using POSIX threads.
3
4 /* Copyright (C) 1998, 1999  Cygnus Solutions
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
23 #if defined (HAVE_PTHREAD_MUTEXATTR_SETTYPE) || defined (HAVE_PTHREAD_MUTEXATTR_SETKIND_NP)
24 #  define HAVE_RECURSIVE_MUTEX 1
25 #endif
26
27
28 //
29 // Typedefs.
30 //
31
32 typedef pthread_cond_t _Jv_ConditionVariable_t;
33
34 #if defined (PTHREAD_MUTEX_HAVE_M_COUNT) || defined (PTHREAD_MUTEX_HAVE___M_COUNT)
35
36 // On Linux we use implementation details of mutexes in order to get
37 // faster results.
38 typedef pthread_mutex_t _Jv_Mutex_t;
39
40 #else /* LINUX_THREADS */
41
42 #define PTHREAD_MUTEX_IS_STRUCT
43
44 typedef struct
45 {
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.
51
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.
56   pthread_cond_t cond;
57   // Thread holding this mutex.  If COUNT is 0, no thread is holding.
58   pthread_t thread;
59 #endif /* HAVE_RECURSIVE_MUTEX */
60
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
66   // recursive mutexes.
67   int count;
68 } _Jv_Mutex_t;
69
70 #endif
71
72 typedef struct
73 {
74   // Flag values are defined in implementation.
75   int flags;
76
77   // Actual thread id.
78   pthread_t thread;
79 } _Jv_Thread_t;
80 typedef void _Jv_ThreadStartFunc (java::lang::Thread *);
81
82
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)
87 {
88 #if ! defined (PTHREAD_MUTEX_IS_STRUCT)
89   return mu;
90 #elif defined (HAVE_RECURSIVE_MUTEX)
91   return &mu->mutex;
92 #else
93   return &mu->mutex2;
94 #endif
95 }
96
97 #include <stdio.h>
98
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.
103 inline int
104 _Jv_PthreadCheckMonitor (_Jv_Mutex_t *mu)
105 {
106   pthread_mutex_t *pmu = _Jv_PthreadGetMutex (mu);
107   // See if the mutex is locked by this thread.
108   if (pthread_mutex_trylock (pmu))
109     return 1;
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;
117 #else
118   int r = mu->count == 0;
119 #endif
120   pthread_mutex_unlock (pmu);
121   return r;
122 }
123
124 //
125 // Condition variables.
126 //
127
128 inline void
129 _Jv_CondInit (_Jv_ConditionVariable_t *cv)
130 {
131   pthread_cond_init (cv, 0);
132 }
133
134 #ifndef LINUX_THREADS
135
136 // pthread_cond_destroy does nothing on Linux and it is a win to avoid
137 // defining this macro.
138
139 #define _Jv_HaveCondDestroy
140
141 inline void
142 _Jv_CondDestroy (_Jv_ConditionVariable_t *cv)
143 {
144   pthread_cond_destroy (cv);
145 }
146
147 #endif /* LINUX_THREADS */
148
149 int _Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu,
150                   jlong millis, jint nanos);
151
152 inline int
153 _Jv_CondNotify (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu)
154 {
155   return _Jv_PthreadCheckMonitor (mu) || pthread_cond_signal (cv);
156 }
157
158 inline int
159 _Jv_CondNotifyAll (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu)
160 {
161   return _Jv_PthreadCheckMonitor (mu) || pthread_cond_broadcast (cv);
162 }
163
164
165 //
166 // Mutexes.
167 //
168
169 #ifdef RECURSIVE_MUTEX_IS_DEFAULT
170 inline void
171 _Jv_MutexInit (_Jv_Mutex_t *mu)
172 {
173   pthread_mutex_init (_Jv_PthreadGetMutex (mu), NULL);
174 #ifdef PTHREAD_MUTEX_IS_STRUCT
175   mu->count = 0;
176 #endif
177 }
178 #else
179 void _Jv_MutexInit (_Jv_Mutex_t *mu);
180 #endif
181
182 #ifndef LINUX_THREADS
183
184 // pthread_mutex_destroy does nothing on Linux and it is a win to avoid
185 // defining this macro.
186
187 #define _Jv_HaveMutexDestroy
188
189 #ifdef HAVE_RECURSIVE_MUTEX
190
191 inline void
192 _Jv_MutexDestroy (_Jv_Mutex_t *mu)
193 {
194   pthread_mutex_destroy (_Jv_PthreadGetMutex (mu));
195 }
196
197 #else /* HAVE_RECURSIVE_MUTEX */
198
199 extern void _Jv_MutexDestroy (_Jv_Mutex_t *mu);
200
201 #endif /* HAVE_RECURSIVE_MUTEX */
202 #endif /* LINUX_THREADS */
203
204 #ifdef HAVE_RECURSIVE_MUTEX
205
206 inline int
207 _Jv_MutexLock (_Jv_Mutex_t *mu)
208 {
209   int r = pthread_mutex_lock (_Jv_PthreadGetMutex (mu));
210 #ifdef PTHREAD_MUTEX_IS_STRUCT
211   if (! r)
212     ++mu->count;
213 #endif
214   return r;
215 }
216
217 inline int
218 _Jv_MutexUnlock (_Jv_Mutex_t *mu)
219 {
220   int r = pthread_mutex_unlock (_Jv_PthreadGetMutex (mu));
221 #ifdef PTHREAD_MUTEX_IS_STRUCT
222   if (! r)
223     --mu->count;
224 #endif
225   return r;
226 }
227
228 #else /* HAVE_RECURSIVE_MUTEX */
229
230 extern int _Jv_MutexLock (_Jv_Mutex_t *mu);
231 extern int _Jv_MutexUnlock (_Jv_Mutex_t *mu);
232
233 #endif /* HAVE_RECURSIVE_MUTEX */
234
235
236 //
237 // Thread creation and manipulation.
238 //
239
240 void _Jv_InitThreads (void);
241
242 void _Jv_ThreadInitData (_Jv_Thread_t **data, java::lang::Thread *thread);
243
244 inline java::lang::Thread *
245 _Jv_ThreadCurrent (void)
246 {
247   extern pthread_key_t _Jv_ThreadKey;
248   return (java::lang::Thread *) pthread_getspecific (_Jv_ThreadKey);
249 }
250
251 inline _Jv_Thread_t *
252 _Jv_ThreadCurrentData (void)
253 {
254   extern pthread_key_t _Jv_ThreadDataKey;
255   return (_Jv_Thread_t *) pthread_getspecific (_Jv_ThreadDataKey);
256 }
257
258 inline void
259 _Jv_ThreadYield (void)
260 {
261 #ifdef HAVE_SCHED_YIELD
262   sched_yield ();
263 #endif /* HAVE_SCHED_YIELD */
264 }
265
266 void _Jv_ThreadSetPriority (_Jv_Thread_t *data, jint prio);
267
268 void _Jv_ThreadStart (java::lang::Thread *thread, _Jv_Thread_t *data,
269                       _Jv_ThreadStartFunc *meth);
270
271 void _Jv_ThreadWait (void);
272
273 void _Jv_ThreadInterrupt (_Jv_Thread_t *data);
274
275 #endif /* __JV_POSIX_THREADS__ */