* Removed all Id tags.
[cacao.git] / src / native / vm / java_lang_Thread.c
1 /* src/native/vm/java_lang_Thread.c - java/lang/Thread functions
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25 */
26
27
28 #include "config.h"
29 #include "vm/types.h"
30
31 #include "native/jni.h"
32 #include "native/llni.h"
33 #include "native/native.h"
34
35 #include "native/include/java_lang_String.h"
36 #include "native/include/java_lang_Object.h"            /* java_lang_Thread.h */
37 #include "native/include/java_lang_Throwable.h"         /* java_lang_Thread.h */
38 #include "native/include/java_lang_Thread.h"
39
40 #if defined(ENABLE_JAVASE)
41 # include "native/include/java_lang_ThreadGroup.h"
42
43 # if defined(WITH_CLASSPATH_GNU)
44 #  include "native/include/java_lang_VMThread.h"
45 # endif
46 #endif
47
48 #include "threads/lock-common.h"
49 #include "threads/threads-common.h"
50
51 #include "toolbox/logging.h"
52
53 #include "vm/builtin.h"
54 #include "vm/exceptions.h"
55 #include "vm/stringlocal.h"
56
57 #include "vmcore/options.h"
58
59
60 /*
61  * Class:     java/lang/Thread
62  * Method:    countStackFrames
63  * Signature: ()I
64  */
65 s4 _Jv_java_lang_Thread_countStackFrames(java_lang_Thread *this)
66 {
67     log_text("java_lang_Thread_countStackFrames called");
68
69     return 0;
70 }
71
72
73 /*
74  * Class:     java/lang/Thread
75  * Method:    sleep
76  * Signature: (J)V
77  */
78 void _Jv_java_lang_Thread_sleep(s8 millis)
79 {
80 #if defined(ENABLE_THREADS)
81         threads_sleep(millis, 0);
82 #endif
83 }
84
85
86 /*
87  * Class:     java/lang/Thread
88  * Method:    start
89  * Signature: (J)V
90  */
91 void _Jv_java_lang_Thread_start(java_lang_Thread *this, s8 stacksize)
92 {
93 #if defined(ENABLE_THREADS)
94         threads_thread_start(this);
95 #endif
96 }
97
98
99 /*
100  * Class:     java/lang/Thread
101  * Method:    interrupt
102  * Signature: ()V
103  */
104 void _Jv_java_lang_Thread_interrupt(java_lang_Thread *this)
105 {
106 #if defined(ENABLE_THREADS)
107         threadobject *thread;
108
109 #if defined(WITH_CLASSPATH_GNU)
110         thread = (threadobject *) LLNI_field_direct(LLNI_field_direct(this, vmThread), vmdata);
111 #elif defined(WITH_CLASSPATH_CLDC1_1)
112         thread = (threadobject *) this->vm_thread;
113 #endif
114
115         threads_thread_interrupt(thread);
116 #endif
117 }
118
119
120 /*
121  * Class:     java/lang/Thread
122  * Method:    isAlive
123  * Signature: ()Z
124  */
125 s4 _Jv_java_lang_Thread_isAlive(java_lang_Thread *this)
126 {
127 #if defined(ENABLE_THREADS)
128         threadobject *t;
129
130 # if defined(WITH_CLASSPATH_GNU)
131
132         t = (threadobject *) LLNI_field_direct(LLNI_field_direct(this, vmThread), vmdata);
133
134 # elif defined(WITH_CLASSPATH_SUN)
135
136         /* XXX this is just a quick hack */
137
138         for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
139                 if (t->object == this)
140                         break;
141         }
142
143         /* The threadobject is null when a thread is created in Java. The
144            priority is set later during startup. */
145
146         if (t == NULL)
147                 return 0;
148
149 # elif defined(WITH_CLASSPATH_CLDC1_1)
150
151         t = (threadobject *) this->vm_thread;
152
153         if (t == NULL)
154                 return 0;
155
156 # else
157 #  error unknown classpath configuration
158 # endif
159
160         return threads_thread_is_alive(t);
161 #else
162         /* if threads are disabled, the only thread running is alive */
163
164         return 1;
165 #endif
166 }
167
168
169 /*
170  * Class:     java/lang/Thread
171  * Method:    isInterrupted
172  * Signature: ()Z
173  */
174 s4 _Jv_java_lang_Thread_isInterrupted(java_lang_Thread *this)
175 {
176 #if defined(ENABLE_THREADS)
177         threadobject *t;
178
179 # if defined(WITH_CLASSPATH_GNU)
180         t = (threadobject *) LLNI_field_direct(LLNI_field_direct(this, vmThread), vmdata);
181 # elif defined(WITH_CLASSPATH_SUN)
182         /* XXX this is just a quick hack */
183
184         for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
185                 if (t->object == this)
186                         break;
187         }
188 # elif defined(WITH_CLASSPATH_CLDC1_1)
189         t = (threadobject *) this->vm_thread;
190 # else
191 #  error unknown classpath configuration
192 # endif
193
194         return threads_thread_has_been_interrupted(t);
195 #else
196         return 0;
197 #endif
198 }
199
200
201 /*
202  * Class:     java/lang/Thread
203  * Method:    suspend
204  * Signature: ()V
205  */
206 void _Jv_java_lang_Thread_suspend(java_lang_Thread *this)
207 {
208 #if defined(ENABLE_THREADS)
209 #endif
210 }
211
212
213 /*
214  * Class:     java/lang/Thread
215  * Method:    resume
216  * Signature: ()V
217  */
218 void _Jv_java_lang_Thread_resume(java_lang_Thread *this)
219 {
220 #if defined(ENABLE_THREADS)
221 #endif
222 }
223
224
225 /*
226  * Class:     java/lang/Thread
227  * Method:    setPriority
228  * Signature: (I)V
229  */
230 void _Jv_java_lang_Thread_setPriority(java_lang_Thread *this, s4 priority)
231 {
232 #if defined(ENABLE_THREADS)
233         threadobject *t;
234
235 # if defined(WITH_CLASSPATH_GNU)
236         t = (threadobject *) LLNI_field_direct(LLNI_field_direct(this, vmThread), vmdata);
237 # elif defined(WITH_CLASSPATH_SUN)
238         /* XXX this is just a quick hack */
239
240         for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
241                 if (t->object == this)
242                         break;
243         }
244
245         /* The threadobject is null when a thread is created in Java. The
246            priority is set later during startup. */
247
248         if (t == NULL)
249                 return;
250 # elif defined(WITH_CLASSPATH_CLDC1_1)
251         t = (threadobject *) this->vm_thread;
252
253         /* The threadobject is null when a thread is created in Java. The
254            priority is set later during startup. */
255
256         if (t == NULL)
257                 return;
258 # else
259 #  error unknown classpath configuration
260 # endif
261
262         threads_set_thread_priority(t->tid, priority);
263 #endif
264 }
265
266
267 /*
268  * Class:     java/lang/Thread
269  * Method:    stop
270  * Signature: (Ljava/lang/Object;)V
271  */
272 void _Jv_java_lang_Thread_stop(java_lang_Thread *this, java_lang_Throwable *t)
273 {
274 #if defined(ENABLE_THREADS)
275 #endif
276 }
277
278
279 /*
280  * Class:     java/lang/Thread
281  * Method:    currentThread
282  * Signature: ()Ljava/lang/Thread;
283  */
284 java_lang_Thread *_Jv_java_lang_Thread_currentThread(void)
285 {
286 #if defined(ENABLE_THREADS)
287         threadobject     *thread;
288 #endif
289         java_lang_Thread *t;
290
291 #if defined(ENABLE_THREADS)
292         thread = THREADOBJECT;
293
294         t = thread->object;
295
296         if (t == NULL)
297                 log_text("t ptr is NULL\n");
298
299 # if defined(ENABLE_JAVASE)
300         if (LLNI_field_direct(t, group) == NULL) {
301                 /* ThreadGroup of currentThread is not initialized */
302
303                 LLNI_field_direct(t, group) = (java_lang_ThreadGroup *)
304                         native_new_and_init(class_java_lang_ThreadGroup);
305
306                 if (LLNI_field_direct(t, group) == NULL)
307                         log_text("unable to create ThreadGroup");
308         }
309 # endif
310 #else
311         /* we just return a fake java.lang.Thread object, otherwise we get
312        NullPointerException's in GNU classpath */
313
314         t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
315 #endif
316
317         return t;
318 }
319
320
321 /*
322  * Class:     java/lang/Thread
323  * Method:    yield
324  * Signature: ()V
325  */
326 void _Jv_java_lang_Thread_yield(void)
327 {
328 #if defined(ENABLE_THREADS)
329         threads_yield();
330 #endif
331 }
332
333
334 /*
335  * Class:     java/lang/Thread
336  * Method:    interrupted
337  * Signature: ()Z
338  */
339 s4 _Jv_java_lang_Thread_interrupted(void)
340 {
341 #if defined(ENABLE_THREADS)
342         return threads_check_if_interrupted_and_reset();
343 #else
344         return 0;
345 #endif
346 }
347
348
349 /*
350  * Class:     java/lang/Thread
351  * Method:    holdsLock
352  * Signature: (Ljava/lang/Object;)Z
353  */
354 s4 _Jv_java_lang_Thread_holdsLock(java_lang_Object* obj)
355 {
356 #if defined(ENABLE_THREADS)
357         java_handle_t *o;
358
359         o = (java_handle_t *) obj;
360
361         if (o == NULL) {
362                 exceptions_throw_nullpointerexception();
363                 return 0;
364         }
365
366         return lock_is_held_by_current_thread(o);
367 #else
368         return 0;
369 #endif
370 }
371
372
373 /*
374  * Class:     java/lang/Thread
375  * Method:    getState
376  * Signature: ()Ljava/lang/String;
377  */
378 java_lang_String *_Jv_java_lang_Thread_getState(java_lang_Thread *this)
379 {
380 #if defined(ENABLE_THREADS)
381         threadobject  *thread;
382         utf           *u;
383         java_handle_t *o;
384
385 # if defined(WITH_CLASSPATH_GNU)
386         thread = (threadobject *) LLNI_field_direct(LLNI_field_direct(this, vmThread), vmdata);
387 # elif defined(WITH_CLASSPATH_CLDC1_1)
388         thread = (threadobject *) this->vm_thread;
389 # endif
390
391         u = threads_thread_get_state(thread);
392         o = javastring_new(u);
393
394         return (java_lang_String *) o;
395 #else
396         return NULL;
397 #endif
398 }
399
400
401 /*
402  * These are local overrides for various environment variables in Emacs.
403  * Please do not remove this and leave it at the end of the file, where
404  * Emacs will automagically detect them.
405  * ---------------------------------------------------------------------
406  * Local variables:
407  * mode: c
408  * indent-tabs-mode: t
409  * c-basic-offset: 4
410  * tab-width: 4
411  * End:
412  */