1 /* src/threads/threads-common.c - machine independent thread functions
3 Copyright (C) 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
8 This file is part of CACAO.
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.
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.
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
25 $Id: threads-common.c 7811 2007-04-25 18:33:30Z twisti $
36 #include "native/jni.h"
38 #include "native/include/java_lang_Object.h"
39 #include "native/include/java_lang_String.h"
40 #include "native/include/java_lang_Thread.h"
42 #if defined(WITH_CLASSPATH_GNU)
43 # include "native/include/java_lang_VMThread.h"
46 #include "threads/threads-common.h"
48 #include "threads/native/threads.h"
50 #include "vm/builtin.h"
51 #include "vm/stringlocal.h"
54 #include "vm/jit/stacktrace.h"
56 #include "vmcore/class.h"
58 #if defined(ENABLE_STATISTICS)
59 # include "vmcore/options.h"
60 # include "vmcore/statistics.h"
63 #include "vmcore/utf8.h"
66 /* threads_create_thread *******************************************************
68 Creates and initializes an internal thread data-structure.
70 *******************************************************************************/
72 threadobject *threads_create_thread(void)
76 /* allocate internal thread data-structure */
78 #if defined(ENABLE_GC_BOEHM)
79 thread = GCNEW_UNCOLLECTABLE(threadobject, 1);
81 thread = NEW(threadobject);
84 #if defined(ENABLE_STATISTICS)
86 size_threadobject += sizeof(threadobject);
89 /* initialize thread data structure */
91 threads_init_threadobject(thread);
92 lock_init_execution_env(thread);
98 /* threads_thread_create_internal **********************************************
100 Creates an internal thread data-structure with the given name, plus
101 necessary Java objects for the VM (e.g. finalizer-thread,
104 *******************************************************************************/
106 threadobject *threads_thread_create_internal(utf *name)
108 threadobject *thread;
110 #if defined(WITH_CLASSPATH_GNU)
111 java_lang_VMThread *vmt;
114 /* create internal thread data-structure */
116 thread = threads_create_thread();
118 /* create the java thread object */
120 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
125 #if defined(WITH_CLASSPATH_GNU)
126 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
132 vmt->vmdata = (java_lang_Object *) thread;
135 #elif defined(WITH_CLASSPATH_CLDC1_1)
136 t->vm_thread = (java_lang_Object *) thread;
140 thread->flags = THREAD_FLAG_DAEMON;
142 /* set java.lang.Thread fields */
144 t->name = (java_lang_String *) javastring_new(name);
145 #if defined(ENABLE_JAVASE)
148 t->priority = NORM_PRIORITY;
150 /* return the thread data-structure */
156 /* threads_start_javathread ****************************************************
158 Start a thread in the JVM. Only the java thread object exists so far.
161 object.....the java thread object java.lang.Thread
163 *******************************************************************************/
165 void threads_start_javathread(java_lang_Thread *object)
167 threadobject *thread;
169 /* create internal thread data-structure */
171 thread = threads_create_thread();
173 /* link the two objects together */
175 thread->object = object;
177 #if defined(ENABLE_JAVASE)
178 /* is this a daemon thread? */
180 if (object->daemon == true)
181 thread->flags |= THREAD_FLAG_DAEMON;
184 #if defined(WITH_CLASSPATH_GNU)
185 assert(object->vmThread);
186 assert(object->vmThread->vmdata == NULL);
188 object->vmThread->vmdata = (java_lang_Object *) thread;
189 #elif defined(WITH_CLASSPATH_CLDC1_1)
190 object->vm_thread = (java_lang_Object *) thread;
193 /* Actually start the thread. Don't pass a function pointer
194 (NULL) since we want Thread.run()V here. */
196 threads_start_thread(thread, NULL);
200 /* threads_get_current_tid *****************************************************
202 Return the tid of the current thread.
207 *******************************************************************************/
209 ptrint threads_get_current_tid(void)
211 threadobject *thread;
213 thread = THREADOBJECT;
215 /* this may happen during bootstrap */
220 return (ptrint) thread->tid;
224 /* threads_thread_get_state ****************************************************
226 Returns the current state of the given thread.
228 *******************************************************************************/
230 utf *threads_thread_get_state(threadobject *thread)
234 switch (thread->state) {
235 case THREAD_STATE_NEW:
236 u = utf_new_char("NEW");
238 case THREAD_STATE_RUNNABLE:
239 u = utf_new_char("RUNNABLE");
241 case THREAD_STATE_BLOCKED:
242 u = utf_new_char("BLOCKED");
244 case THREAD_STATE_WAITING:
245 u = utf_new_char("WAITING");
247 case THREAD_STATE_TIMED_WAITING:
248 u = utf_new_char("TIMED_WAITING");
250 case THREAD_STATE_TERMINATED:
251 u = utf_new_char("TERMINATED");
254 vm_abort("threads_get_state: unknown thread state %d", thread->state);
261 /* threads_thread_is_alive *****************************************************
263 Returns if the give thread is alive.
265 *******************************************************************************/
267 bool threads_thread_is_alive(threadobject *thread)
271 switch (thread->state) {
272 case THREAD_STATE_NEW:
273 case THREAD_STATE_TERMINATED:
277 case THREAD_STATE_RUNNABLE:
278 case THREAD_STATE_BLOCKED:
279 case THREAD_STATE_WAITING:
280 case THREAD_STATE_TIMED_WAITING:
285 vm_abort("threads_is_alive: unknown thread state %d", thread->state);
292 /* threads_dump ****************************************************************
294 Dumps info for all threads running in the JVM. This function is
295 called when SIGQUIT (<ctrl>-\) is sent to CACAO.
297 *******************************************************************************/
299 void threads_dump(void)
301 threadobject *thread;
305 /* XXX we should stop the world here */
307 printf("Full thread dump CACAO "VERSION":\n");
309 /* iterate over all started threads */
311 thread = mainthreadobj;
314 /* get thread object */
318 /* the thread may be currently in initalization, don't print it */
321 /* get thread name */
323 #if defined(ENABLE_JAVASE)
324 name = javastring_toutf((java_objectheader *) t->name, false);
325 #elif defined(ENABLE_JAVAME_CLDC1_1)
330 utf_display_printable_ascii(name);
333 if (thread->flags & THREAD_FLAG_DAEMON)
336 printf(" prio=%d", t->priority);
338 #if SIZEOF_VOID_P == 8
339 printf(" tid=0x%016lx (%ld)",
340 (ptrint) thread->tid, (ptrint) thread->tid);
342 printf(" tid=0x%08lx (%ld)",
343 (ptrint) thread->tid, (ptrint) thread->tid);
346 /* print thread state */
348 switch (thread->state) {
349 case THREAD_STATE_NEW:
352 case THREAD_STATE_RUNNABLE:
355 case THREAD_STATE_BLOCKED:
358 case THREAD_STATE_WAITING:
361 case THREAD_STATE_TIMED_WAITING:
362 printf(" waiting on condition");
364 case THREAD_STATE_TERMINATED:
365 printf(" terminated");
368 vm_abort("threads_dump: unknown thread state %d",
374 /* print trace of thread */
376 threads_thread_print_stacktrace(thread);
379 thread = thread->next;
380 } while ((thread != NULL) && (thread != mainthreadobj));
384 /* threads_thread_print_stacktrace *********************************************
386 Print the current stacktrace of the current thread.
388 *******************************************************************************/
390 void threads_thread_print_stacktrace(threadobject *thread)
393 stacktracebuffer *stb;
396 /* mark start of dump memory area */
398 dumpsize = dump_size();
400 /* create a stacktrace for the passed thread */
402 sfi = thread->_stackframeinfo;
404 stb = stacktrace_create(sfi);
406 /* print stacktrace */
409 stacktrace_print_trace_from_buffer(stb);
411 puts("\t<<No stacktrace available>>");
415 dump_release(dumpsize);
419 /* threads_print_stacktrace ****************************************************
421 Print the current stacktrace of the current thread.
423 *******************************************************************************/
425 void threads_print_stacktrace(void)
427 threadobject *thread;
429 thread = THREADOBJECT;
431 threads_thread_print_stacktrace(thread);
436 * These are local overrides for various environment variables in Emacs.
437 * Please do not remove this and leave it at the end of the file, where
438 * Emacs will automagically detect them.
439 * ---------------------------------------------------------------------
442 * indent-tabs-mode: t
446 * vim:noexpandtab:sw=4:ts=4: