* error.c (dump_function_name): Don't crash if given a friend
[official-gcc.git] / libjava / include / posix-threads.h
blobf49528354404d15f2fb003ae2b786efbf872b708
1 // -*- c++ -*-
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
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>
23 #if defined (HAVE_PTHREAD_MUTEXATTR_SETTYPE) || defined (HAVE_PTHREAD_MUTEXATTR_SETKIND_NP)
24 # define HAVE_RECURSIVE_MUTEX 1
25 #endif
29 // Typedefs.
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
37 // faster results.
38 typedef pthread_mutex_t _Jv_Mutex_t;
40 #else /* LINUX_THREADS */
42 #define PTHREAD_MUTEX_IS_STRUCT
44 typedef 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.
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 */
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;
70 #endif
72 typedef struct
74 // Flag values are defined in implementation.
75 int flags;
77 // Actual thread id.
78 pthread_t thread;
79 } _Jv_Thread_t;
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)
89 return mu;
90 #elif defined (HAVE_RECURSIVE_MUTEX)
91 return &mu->mutex;
92 #else
93 return &mu->mutex2;
94 #endif
97 #include <stdio.h>
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)
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;
125 // Condition variables.
128 inline void
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
141 inline void
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);
152 inline int
153 _Jv_CondNotify (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu)
155 return _Jv_PthreadCheckMonitor (mu) || pthread_cond_signal (cv);
158 inline int
159 _Jv_CondNotifyAll (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu)
161 return _Jv_PthreadCheckMonitor (mu) || pthread_cond_broadcast (cv);
166 // Mutexes.
169 #ifdef RECURSIVE_MUTEX_IS_DEFAULT
170 inline void
171 _Jv_MutexInit (_Jv_Mutex_t *mu)
173 pthread_mutex_init (_Jv_PthreadGetMutex (mu), NULL);
174 #ifdef PTHREAD_MUTEX_IS_STRUCT
175 mu->count = 0;
176 #endif
178 #else
179 void _Jv_MutexInit (_Jv_Mutex_t *mu);
180 #endif
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
191 inline void
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
206 inline int
207 _Jv_MutexLock (_Jv_Mutex_t *mu)
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;
217 inline int
218 _Jv_MutexUnlock (_Jv_Mutex_t *mu)
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;
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);
258 inline void
259 _Jv_ThreadYield (void)
261 #ifdef HAVE_SCHED_YIELD
262 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__ */