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