* merged with tip (040f180a056b)
[cacao.git] / src / threads / posix / thread-posix.hpp
1 /* src/threads/posix/thread-posix.hpp - POSIX thread functions
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #ifndef _THREAD_POSIX_HPP
27 #define _THREAD_POSIX_HPP
28
29 /* forward typedefs ***********************************************************/
30
31 typedef struct threadobject threadobject;
32
33
34 #include "config.h"
35
36 #include <pthread.h>
37 #include <ucontext.h>
38
39 #include "vm/types.h"
40
41 #include "mm/memory.h"
42
43 #if defined(ENABLE_TLH)
44 #include "mm/tlh.h"
45 #endif
46
47 #include "native/localref.h"
48
49 #include "threads/condition.hpp"
50 #include "threads/mutex.hpp"
51
52 #include "threads/posix/lock.h"
53
54 #include "vm/global.h"
55 #include "vm/vm.hpp"
56
57 #if defined(ENABLE_GC_CACAO)
58 # include "vm/jit/executionstate.h"
59 # include "vm/jit/replace.h"
60 #endif
61
62 #include "vm/jit/stacktrace.hpp"
63
64 #if defined(ENABLE_INTRP)
65 #include "vm/jit/intrp/intrp.h"
66 #endif
67
68 #if defined(__DARWIN__)
69 # include <mach/mach.h>
70
71 typedef struct {
72         Mutex* mutex;
73         Condition* cond;
74         int value;
75 } sem_t;
76
77 #else
78 # include <semaphore.h>
79 #endif
80
81
82 // FIXME
83 #ifdef __cplusplus
84 extern "C" {
85 #endif
86
87 /* current threadobject *******************************************************/
88
89 #if defined(HAVE___THREAD)
90
91 #define THREADOBJECT      thread_current
92
93 extern __thread threadobject *thread_current;
94
95 #else /* defined(HAVE___THREAD) */
96
97 #define THREADOBJECT \
98         ((threadobject *) pthread_getspecific(thread_current_key))
99
100 extern pthread_key_t thread_current_key;
101
102 #endif /* defined(HAVE___THREAD) */
103
104
105 /* threadobject ****************************************************************
106
107    Struct holding thread local variables.
108
109 *******************************************************************************/
110
111 #define THREAD_FLAG_JAVA        0x01    /* a normal Java thread               */
112 #define THREAD_FLAG_INTERNAL    0x02    /* CACAO internal thread              */
113 #define THREAD_FLAG_DAEMON      0x04    /* daemon thread                      */
114 #define THREAD_FLAG_IN_NATIVE   0x08    /* currently executing native code    */
115
116 #define SUSPEND_REASON_JNI       1      /* suspended from JNI                 */
117 #define SUSPEND_REASON_STOPWORLD 2      /* suspended from stop-thw-world      */
118
119
120 struct threadobject {
121         java_object_t        *object;       /* link to java.lang.Thread object    */
122
123         ptrint                thinlock;     /* pre-computed thin lock value       */
124
125         s4                    index;        /* thread index, starting with 1      */
126         u4                    flags;        /* flag field                         */
127         u4                    state;        /* state field                        */
128
129         pthread_t             tid;          /* pthread id                         */
130
131 #if defined(__DARWIN__)
132         mach_port_t           mach_thread;       /* Darwin thread id              */
133 #endif
134
135         /* for the sable tasuki lock extension */
136         bool                  flc_bit;
137         struct threadobject  *flc_list;     /* FLC list head for this thread      */
138         struct threadobject  *flc_next;     /* next pointer for FLC list          */
139         java_handle_t        *flc_object;
140         Mutex*                flc_lock;     /* controlling access to these fields */
141         Condition*            flc_cond;
142
143         /* these are used for the wait/notify implementation                      */
144         Mutex*                waitmutex;
145         Condition*            waitcond;
146
147         Mutex*                suspendmutex; /* lock before suspending this thread */
148         Condition*            suspendcond;  /* notify to resume this thread       */
149
150         bool                  interrupted;
151         bool                  signaled;
152
153         bool                  suspended;    /* is this thread suspended?          */
154         s4                    suspend_reason; /* reason for suspending            */
155
156         u1                   *pc;           /* current PC (used for profiling)    */
157
158         java_object_t        *_exceptionptr;     /* current exception             */
159         stackframeinfo_t     *_stackframeinfo;   /* current native stackframeinfo */
160         localref_table       *_localref_table;   /* JNI local references          */
161
162 #if defined(ENABLE_INTRP)
163         Cell                 *_global_sp;        /* stack pointer for interpreter */
164 #endif
165
166 #if defined(ENABLE_GC_CACAO)
167         bool                  gc_critical;  /* indicates a critical section       */
168
169         sourcestate_t        *ss;
170         executionstate_t     *es;
171 #endif
172
173         dumpinfo_t            dumpinfo;     /* dump memory info structure         */
174
175 #if defined(ENABLE_DEBUG_FILTER)
176         u2                    filterverbosecallctr[2]; /* counters for verbose call filter */
177 #endif
178
179 #if !defined(NDEBUG)
180         s4                    tracejavacallindent;
181         u4                    tracejavacallcount;
182 #endif
183
184 #if defined(ENABLE_TLH)
185         tlh_t                 tlh;
186 #endif
187
188 #if defined(ENABLE_ESCAPE_REASON)
189         void *escape_reasons;
190 #endif
191
192         listnode_t            linkage;      /* threads-list                       */
193         listnode_t            linkage_free; /* free-list                          */
194 };
195
196
197 /* native-world flags *********************************************************/
198
199 #if defined(ENABLE_GC_CACAO)
200 # define THREAD_NATIVEWORLD_ENTER THREADOBJECT->flags |=  THREAD_FLAG_IN_NATIVE
201 # define THREAD_NATIVEWORLD_EXIT  THREADOBJECT->flags &= ~THREAD_FLAG_IN_NATIVE
202 #else
203 # define THREAD_NATIVEWORLD_ENTER /*nop*/
204 # define THREAD_NATIVEWORLD_EXIT  /*nop*/
205 #endif
206
207
208 /* counter for verbose call filter ********************************************/
209
210 #if defined(ENABLE_DEBUG_FILTER)
211 #       define FILTERVERBOSECALLCTR (THREADOBJECT->filterverbosecallctr)
212 #endif
213
214 /* state for trace java call **************************************************/
215
216 #if !defined(NDEBUG)
217 #       define TRACEJAVACALLINDENT (THREADOBJECT->tracejavacallindent)
218 #       define TRACEJAVACALLCOUNT (THREADOBJECT->tracejavacallcount)
219 #endif
220
221
222 /* inline functions ***********************************************************/
223
224 /* thread_get_current **********************************************************
225
226    Return the threadobject of the current thread.
227    
228    RETURN:
229        the current threadobject *
230
231 *******************************************************************************/
232
233 inline static threadobject *thread_get_current(void)
234 {
235         threadobject *t;
236
237 #if defined(HAVE___THREAD)
238         t = thread_current;
239 #else
240         t = (threadobject *) pthread_getspecific(thread_current_key);
241 #endif
242
243         return t;
244 }
245
246
247 /* thread_set_current **********************************************************
248
249    Set the current thread object.
250    
251    IN:
252       t ... the thread object to set
253
254 *******************************************************************************/
255
256 inline static void thread_set_current(threadobject *t)
257 {
258 #if defined(HAVE___THREAD)
259         thread_current = t;
260 #else
261         int result;
262
263         result = pthread_setspecific(thread_current_key, t);
264
265         if (result != 0)
266                 vm_abort_errnum(result, "thread_set_current: pthread_setspecific failed");
267 #endif
268 }
269
270
271 inline static stackframeinfo_t *threads_get_current_stackframeinfo(void)
272 {
273         return THREADOBJECT->_stackframeinfo;
274 }
275
276 inline static void threads_set_current_stackframeinfo(stackframeinfo_t *sfi)
277 {
278         THREADOBJECT->_stackframeinfo = sfi;
279 }
280
281
282 /* functions ******************************************************************/
283
284 void threads_sem_init(sem_t *sem, bool shared, int value);
285 void threads_sem_wait(sem_t *sem);
286 void threads_sem_post(sem_t *sem);
287
288 void threads_start_thread(threadobject *thread, functionptr function);
289
290 void threads_set_thread_priority(pthread_t tid, int priority);
291
292 #if defined(ENABLE_GC_CACAO)
293 bool threads_suspend_thread(threadobject *thread, s4 reason);
294 void threads_suspend_ack(u1* pc, u1* sp);
295 bool threads_resume_thread(threadobject *thread);
296 #endif
297
298 void threads_join_all_threads(void);
299
300 void threads_sleep(int64_t millis, int32_t nanos);
301
302 void threads_wait_with_timeout_relative(threadobject *t, s8 millis, s4 nanos);
303
304 void threads_thread_interrupt(threadobject *thread);
305
306 #if defined(ENABLE_TLH)
307 void threads_tlh_add_frame();
308 void threads_tlh_remove_frame();
309 #endif
310
311 #ifdef __cplusplus
312 } // extern "C"
313 #endif
314
315 #endif // _THREAD_POSIX_HPP
316
317
318 /*
319  * These are local overrides for various environment variables in Emacs.
320  * Please do not remove this and leave it at the end of the file, where
321  * Emacs will automagically detect them.
322  * ---------------------------------------------------------------------
323  * Local variables:
324  * mode: c++
325  * indent-tabs-mode: t
326  * c-basic-offset: 4
327  * tab-width: 4
328  * End:
329  * vim:noexpandtab:sw=4:ts=4:
330  */