interrupt() / notify() fix.
[cacao.git] / src / threads / native / threads.h
1 /* src/threads/native/threads.h - native threads header
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 _THREADS_H
27 #define _THREADS_H
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 #include "native/jni.h"
43 #include "native/localref.h"
44
45 #include "threads/native/lock.h"
46
47 #include "vm/global.h"
48
49 #if defined(ENABLE_GC_CACAO)
50 # include "vm/jit/replace.h"
51 #endif
52
53 #include "vm/jit/stacktrace.h"
54
55 #if defined(ENABLE_INTRP)
56 #include "vm/jit/intrp/intrp.h"
57 #endif
58
59 #if defined(__DARWIN__)
60 # include <mach/mach.h>
61
62 typedef struct {
63         pthread_mutex_t mutex;
64         pthread_cond_t cond;
65         int value;
66 } sem_t;
67
68 #else
69 # include <semaphore.h>
70 #endif
71
72
73 /* current threadobject *******************************************************/
74
75 #if defined(HAVE___THREAD)
76
77 #define THREADSPECIFIC    __thread
78 #define THREADOBJECT      threads_current_threadobject
79
80 extern __thread threadobject *threads_current_threadobject;
81
82 #else /* defined(HAVE___THREAD) */
83
84 #define THREADSPECIFIC
85 #define THREADOBJECT \
86         ((threadobject *) pthread_getspecific(threads_current_threadobject_key))
87
88 extern pthread_key_t threads_current_threadobject_key;
89
90 #endif /* defined(HAVE___THREAD) */
91
92
93 /* threadobject ****************************************************************
94
95    Struct holding thread local variables.
96
97 *******************************************************************************/
98
99 #define THREAD_FLAG_JAVA        0x01    /* a normal Java thread               */
100 #define THREAD_FLAG_INTERNAL    0x02    /* CACAO internal thread              */
101 #define THREAD_FLAG_DAEMON      0x04    /* daemon thread                      */
102 #define THREAD_FLAG_IN_NATIVE   0x08    /* currently executing native code    */
103
104 #define SUSPEND_REASON_JNI       1      /* suspended from JNI                 */
105 #define SUSPEND_REASON_STOPWORLD 2      /* suspended from stop-thw-world      */
106
107
108 struct threadobject {
109         java_object_t        *object;       /* link to java.lang.Thread object    */
110
111         ptrint                thinlock;     /* pre-computed thin lock value       */
112
113         s4                    index;        /* thread index, starting with 1      */
114         u4                    flags;        /* flag field                         */
115         u4                    state;        /* state field                        */
116
117         pthread_t             tid;          /* pthread id                         */
118
119 #if defined(__DARWIN__)
120         mach_port_t           mach_thread;       /* Darwin thread id              */
121 #endif
122
123         /* for the sable tasuki lock extension */
124         bool                  flc_bit;
125         struct threadobject  *flc_list;     /* FLC list head for this thread      */
126         struct threadobject  *flc_next;     /* next pointer for FLC list          */
127         java_handle_t        *flc_object;
128         pthread_mutex_t       flc_lock;     /* controlling access to these fields */
129         pthread_cond_t        flc_cond;
130
131         /* these are used for the wait/notify implementation                      */
132         pthread_mutex_t       waitmutex;
133         pthread_cond_t        waitcond;
134
135         pthread_mutex_t       suspendmutex; /* lock before suspending this thread */
136         pthread_cond_t        suspendcond;  /* notify to resume this thread       */
137
138         bool                  interrupted;
139         bool                  signaled;
140         bool                  sleeping;
141
142         bool                  suspended;    /* is this thread suspended?          */
143         s4                    suspend_reason; /* reason for suspending            */
144
145         u1                   *pc;           /* current PC (used for profiling)    */
146
147         java_object_t        *_exceptionptr;     /* current exception             */
148         stackframeinfo_t     *_stackframeinfo;   /* current native stackframeinfo */
149         localref_table       *_localref_table;   /* JNI local references          */
150
151 #if defined(ENABLE_INTRP)
152         Cell                 *_global_sp;        /* stack pointer for interpreter */
153 #endif
154
155 #if defined(ENABLE_GC_CACAO)
156         bool                  gc_critical;  /* indicates a critical section       */
157
158         sourcestate_t        *ss;
159         executionstate_t     *es;
160 #endif
161
162         dumpinfo_t            dumpinfo;     /* dump memory info structure         */
163
164 #if defined(ENABLE_DEBUG_FILTER)
165         u2                    filterverbosecallctr[2]; /* counters for verbose call filter */
166 #endif
167
168 #if !defined(NDEBUG)
169         s4                    tracejavacallindent;
170         u4                    tracejavacallcount;
171 #endif
172
173         listnode_t            linkage;      /* threads-list                       */
174         listnode_t            linkage_free; /* free-list                          */
175 };
176
177
178 /* native-world flags *********************************************************/
179
180 #if defined(ENABLE_GC_CACAO)
181 # define THREAD_NATIVEWORLD_ENTER THREADOBJECT->flags |=  THREAD_FLAG_IN_NATIVE
182 # define THREAD_NATIVEWORLD_EXIT  THREADOBJECT->flags &= ~THREAD_FLAG_IN_NATIVE
183 #else
184 # define THREAD_NATIVEWORLD_ENTER /*nop*/
185 # define THREAD_NATIVEWORLD_EXIT  /*nop*/
186 #endif
187
188
189 /* counter for verbose call filter ********************************************/
190
191 #if defined(ENABLE_DEBUG_FILTER)
192 #       define FILTERVERBOSECALLCTR (THREADOBJECT->filterverbosecallctr)
193 #endif
194
195 /* state for trace java call **************************************************/
196
197 #if !defined(NDEBUG)
198 #       define TRACEJAVACALLINDENT (THREADOBJECT->tracejavacallindent)
199 #       define TRACEJAVACALLCOUNT (THREADOBJECT->tracejavacallcount)
200 #endif
201
202
203 /* inline functions ***********************************************************/
204
205 inline static stackframeinfo_t *threads_get_current_stackframeinfo(void)
206 {
207         return THREADOBJECT->_stackframeinfo;
208 }
209
210 inline static void threads_set_current_stackframeinfo(stackframeinfo_t *sfi)
211 {
212         THREADOBJECT->_stackframeinfo = sfi;
213 }
214
215
216 /* functions ******************************************************************/
217
218 void threads_sem_init(sem_t *sem, bool shared, int value);
219 void threads_sem_wait(sem_t *sem);
220 void threads_sem_post(sem_t *sem);
221
222 threadobject *threads_get_current_threadobject(void);
223
224 bool threads_init(void);
225
226 void threads_start_thread(threadobject *thread, functionptr function);
227
228 void threads_set_thread_priority(pthread_t tid, int priority);
229
230 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon);
231 bool threads_detach_thread(threadobject *thread);
232
233 bool threads_suspend_thread(threadobject *thread, s4 reason);
234 void threads_suspend_ack(u1* pc, u1* sp);
235 bool threads_resume_thread(threadobject *thread);
236
237 void threads_join_all_threads(void);
238
239 void threads_sleep(s8 millis, s4 nanos);
240
241 void threads_wait_with_timeout_relative(threadobject *t, s8 millis, s4 nanos);
242
243 void threads_thread_interrupt(threadobject *thread);
244 bool threads_check_if_interrupted_and_reset(void);
245 bool threads_thread_has_been_interrupted(threadobject *thread);
246
247 #if !defined(DISABLE_GC)
248 void threads_stopworld(void);
249 void threads_startworld(void);
250 #endif
251
252 #endif /* _THREADS_H */
253
254
255 /*
256  * These are local overrides for various environment variables in Emacs.
257  * Please do not remove this and leave it at the end of the file, where
258  * Emacs will automagically detect them.
259  * ---------------------------------------------------------------------
260  * Local variables:
261  * mode: c
262  * indent-tabs-mode: t
263  * c-basic-offset: 4
264  * tab-width: 4
265  * End:
266  * vim:noexpandtab:sw=4:ts=4:
267  */