1 /* src/threads/native/threads.c - native threads support
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
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.c 7918 2007-05-20 20:42:18Z michi $
32 /* XXX cleanup these includes */
37 #include <sys/types.h>
50 #if !defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
51 # include "machine-instr.h"
53 # include "threads/native/generic-primitives.h"
56 #include "mm/gc-common.h"
57 #include "mm/memory.h"
59 #include "native/jni.h"
60 #include "native/native.h"
61 #include "native/include/java_lang_Object.h"
62 #include "native/include/java_lang_String.h"
63 #include "native/include/java_lang_Throwable.h"
64 #include "native/include/java_lang_Thread.h"
66 #if defined(ENABLE_JAVASE)
67 # include "native/include/java_lang_ThreadGroup.h"
70 #if defined(WITH_CLASSPATH_GNU)
71 # include "native/include/java_lang_VMThread.h"
74 #include "threads/lock-common.h"
75 #include "threads/threads-common.h"
77 #include "threads/native/threads.h"
79 #include "toolbox/logging.h"
81 #include "vm/builtin.h"
82 #include "vm/exceptions.h"
83 #include "vm/global.h"
84 #include "vm/stringlocal.h"
87 #include "vm/jit/asmpart.h"
89 #include "vmcore/options.h"
91 #if defined(ENABLE_STATISTICS)
92 # include "vmcore/statistics.h"
95 #if !defined(__DARWIN__)
96 # if defined(__LINUX__)
97 # define GC_LINUX_THREADS
98 # elif defined(__MIPS__)
99 # define GC_IRIX_THREADS
101 # include <semaphore.h>
102 # if defined(ENABLE_GC_BOEHM)
103 # include "mm/boehm-gc/include/gc.h"
107 #if defined(ENABLE_JVMTI)
108 #include "native/jvmti/cacaodbg.h"
111 #if defined(__DARWIN__)
112 /* Darwin has no working semaphore implementation. This one is taken
116 This is a very simple semaphore implementation for darwin. It
117 is implemented in terms of pthreads calls so it isn't async signal
118 safe. This isn't a problem because signals aren't used to
119 suspend threads on darwin.
122 static int sem_init(sem_t *sem, int pshared, int value)
129 if (pthread_mutex_init(&sem->mutex, NULL) < 0)
132 if (pthread_cond_init(&sem->cond, NULL) < 0)
138 static int sem_post(sem_t *sem)
140 if (pthread_mutex_lock(&sem->mutex) < 0)
145 if (pthread_cond_signal(&sem->cond) < 0) {
146 pthread_mutex_unlock(&sem->mutex);
150 if (pthread_mutex_unlock(&sem->mutex) < 0)
156 static int sem_wait(sem_t *sem)
158 if (pthread_mutex_lock(&sem->mutex) < 0)
161 while (sem->value == 0) {
162 pthread_cond_wait(&sem->cond, &sem->mutex);
167 if (pthread_mutex_unlock(&sem->mutex) < 0)
173 static int sem_destroy(sem_t *sem)
175 if (pthread_cond_destroy(&sem->cond) < 0)
178 if (pthread_mutex_destroy(&sem->mutex) < 0)
183 #endif /* defined(__DARWIN__) */
186 /* internally used constants **************************************************/
188 /* CAUTION: Do not change these values. Boehm GC code depends on them. */
189 #define STOPWORLD_FROM_GC 1
190 #define STOPWORLD_FROM_CLASS_NUMBERING 2
193 /* startupinfo *****************************************************************
195 Struct used to pass info from threads_start_thread to
196 threads_startup_thread.
198 ******************************************************************************/
201 threadobject *thread; /* threadobject for this thread */
202 functionptr function; /* function to run in the new thread */
203 sem_t *psem; /* signals when thread has been entered */
204 /* in the thread list */
205 sem_t *psem_first; /* signals when pthread_create has returned */
209 /* prototypes *****************************************************************/
211 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
214 /******************************************************************************/
215 /* GLOBAL VARIABLES */
216 /******************************************************************************/
218 static methodinfo *method_thread_init;
220 /* the thread object of the current thread */
221 /* This is either a thread-local variable defined with __thread, or */
222 /* a thread-specific value stored with key threads_current_threadobject_key. */
223 #if defined(HAVE___THREAD)
224 __thread threadobject *threads_current_threadobject;
226 pthread_key_t threads_current_threadobject_key;
229 /* global mutex for the threads table */
230 static pthread_mutex_t mutex_threads_table;
232 /* global mutex for stop-the-world */
233 static pthread_mutex_t stopworldlock;
235 /* global mutex and condition for joining threads on exit */
236 static pthread_mutex_t mutex_join;
237 static pthread_cond_t cond_join;
239 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
241 static volatile int stopworldwhere;
243 /* semaphore used for acknowleding thread suspension */
244 static sem_t suspend_ack;
245 #if defined(__MIPS__)
246 static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
247 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
250 /* mutexes used by the fake atomic instructions */
251 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
252 pthread_mutex_t _atomic_add_lock = PTHREAD_MUTEX_INITIALIZER;
253 pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
254 pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
258 /* threads_sem_init ************************************************************
260 Initialize a semaphore. Checks against errors and interruptions.
263 sem..............the semaphore to initialize
264 shared...........true if this semaphore will be shared between processes
265 value............the initial value for the semaphore
267 *******************************************************************************/
269 void threads_sem_init(sem_t *sem, bool shared, int value)
276 r = sem_init(sem, shared, value);
279 } while (errno == EINTR);
281 vm_abort("sem_init failed: %s", strerror(errno));
285 /* threads_sem_wait ************************************************************
287 Wait for a semaphore, non-interruptible.
289 IMPORTANT: Always use this function instead of `sem_wait` directly, as
290 `sem_wait` may be interrupted by signals!
293 sem..............the semaphore to wait on
295 *******************************************************************************/
297 void threads_sem_wait(sem_t *sem)
307 } while (errno == EINTR);
309 vm_abort("sem_wait failed: %s", strerror(errno));
313 /* threads_sem_post ************************************************************
315 Increase the count of a semaphore. Checks for errors.
318 sem..............the semaphore to increase the count of
320 *******************************************************************************/
322 void threads_sem_post(sem_t *sem)
328 /* unlike sem_wait, sem_post is not interruptible */
334 vm_abort("sem_post failed: %s", strerror(errno));
338 /* lock_stopworld **************************************************************
340 Enter the stopworld lock, specifying why the world shall be stopped.
343 where........ STOPWORLD_FROM_GC (1) from within GC
344 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
346 ******************************************************************************/
348 void lock_stopworld(int where)
350 pthread_mutex_lock(&stopworldlock);
351 stopworldwhere = where;
355 /* unlock_stopworld ************************************************************
357 Release the stopworld lock.
359 ******************************************************************************/
361 void unlock_stopworld(void)
364 pthread_mutex_unlock(&stopworldlock);
367 #if defined(__DARWIN__)
368 /* Caller must hold threadlistlock */
369 static void threads_cast_darwinstop(void)
371 threadobject *tobj = mainthreadobj;
372 threadobject *self = THREADOBJECT;
377 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
378 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
379 #if defined(__I386__)
380 i386_thread_state_t thread_state;
382 ppc_thread_state_t thread_state;
384 mach_port_t thread = tobj->mach_thread;
387 r = thread_suspend(thread);
389 if (r != KERN_SUCCESS)
390 vm_abort("thread_suspend failed");
392 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
393 &thread_state_count);
395 if (r != KERN_SUCCESS)
396 vm_abort("thread_get_state failed");
398 md_critical_section_restart((ucontext_t *) &thread_state);
400 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
403 if (r != KERN_SUCCESS)
404 vm_abort("thread_set_state failed");
408 } while (tobj != mainthreadobj);
411 static void threads_cast_darwinresume(void)
413 threadobject *tobj = mainthreadobj;
414 threadobject *self = THREADOBJECT;
419 mach_port_t thread = tobj->mach_thread;
422 r = thread_resume(thread);
424 if (r != KERN_SUCCESS)
425 vm_abort("thread_resume failed");
429 } while (tobj != mainthreadobj);
434 #if defined(__MIPS__)
435 static void threads_cast_irixresume(void)
437 pthread_mutex_lock(&suspend_ack_lock);
438 pthread_cond_broadcast(&suspend_cond);
439 pthread_mutex_unlock(&suspend_ack_lock);
443 #if !defined(DISABLE_GC)
445 void threads_cast_stopworld(void)
447 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
451 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
453 /* lock the threads table */
455 threads_table_lock();
457 #if defined(__DARWIN__)
458 threads_cast_darwinstop();
459 #elif defined(__CYGWIN__)
463 /* send all threads the suspend signal */
465 threads_cast_sendsignals(GC_signum1());
467 /* wait for all threads to suspend (except the current one) */
469 count = threads_table_get_threads() - 1;
471 for (i = 0; i < count; i++)
472 threads_sem_wait(&suspend_ack);
475 /* unlock the threads table */
477 threads_table_unlock();
480 void threads_cast_startworld(void)
482 /* lock the threads table */
484 threads_table_lock();
486 #if defined(__DARWIN__)
487 threads_cast_darwinresume();
488 #elif defined(__MIPS__)
489 threads_cast_irixresume();
490 #elif defined(__CYGWIN__)
494 threads_cast_sendsignals(GC_signum2());
497 /* unlock the threads table */
499 threads_table_unlock();
505 #if !defined(__DARWIN__)
506 static void threads_sigsuspend_handler(ucontext_t *_uc)
511 /* XXX TWISTI: this is just a quick hack */
512 #if defined(ENABLE_JIT)
513 md_critical_section_restart(_uc);
516 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
517 (not POSIX async-safe). */
518 #if defined(__IRIX__)
519 pthread_mutex_lock(&suspend_ack_lock);
520 threads_sem_post(&suspend_ack);
521 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
522 pthread_mutex_unlock(&suspend_ack_lock);
523 #elif defined(__CYGWIN__)
527 threads_sem_post(&suspend_ack);
531 sigdelset(&sigs, sig);
539 /* threads_stopworld ***********************************************************
541 Stops the world from turning. All threads except the calling one
542 are suspended. The function returns as soon as all threads have
543 acknowledged their suspension.
545 *******************************************************************************/
547 #if !defined(DISABLE_GC)
548 void threads_stopworld(void)
550 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
551 threadobject *tobj = mainthreadobj;
552 threadobject *self = THREADOBJECT;
557 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
558 pthread_mutex_lock(&threadlistlock);
560 #if defined(__DARWIN__)
561 threads_cast_darwinstop();
562 #elif defined(__CYGWIN__)
566 /* count how many threads we suspended */
569 /* suspend all running threads */
572 result = threads_suspend_thread(tobj, SUSPEND_REASON_STOPWORLD);
577 } while (tobj != mainthreadobj);
579 /* wait till all threads are suspended */
580 for (i = 0; i < count; i++)
581 threads_sem_wait(&suspend_ack);
584 pthread_mutex_unlock(&threadlistlock);
586 #endif /* !defined(DISABLE_GC) */
589 /* threads_startworld **********************************************************
591 Starts the world again after it has previously been stopped.
593 *******************************************************************************/
595 #if !defined(DISABLE_GC)
596 void threads_startworld(void)
598 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
599 threadobject *tobj = mainthreadobj;
600 threadobject *self = THREADOBJECT;
604 pthread_mutex_lock(&threadlistlock);
606 #if defined(__DARWIN__)
607 threads_cast_darwinresume();
608 #elif defined(__MIPS__)
609 threads_cast_irixresume();
610 #elif defined(__CYGWIN__)
614 /* resume all thread we haltet */
617 result = threads_resume_thread(tobj);
621 } while (tobj != mainthreadobj);
624 pthread_mutex_unlock(&threadlistlock);
627 #endif /* DISABLE_GC */
630 /* threads_set_current_threadobject ********************************************
632 Set the current thread object.
635 thread.......the thread object to set
637 *******************************************************************************/
639 void threads_set_current_threadobject(threadobject *thread)
641 #if !defined(HAVE___THREAD)
642 if (pthread_setspecific(threads_current_threadobject_key, thread) != 0)
643 vm_abort("threads_set_current_threadobject: pthread_setspecific failed: %s", strerror(errno));
645 threads_current_threadobject = thread;
650 /* threads_impl_thread_new *****************************************************
652 Initialize implementation fields of a threadobject.
655 t....the threadobject
657 *******************************************************************************/
659 void threads_impl_thread_new(threadobject *t)
661 /* get the pthread id */
663 t->tid = pthread_self();
665 /* initialize the mutex and the condition */
667 pthread_mutex_init(&(t->waitmutex), NULL);
668 pthread_cond_init(&(t->waitcond), NULL);
672 /* threads_impl_thread_free ****************************************************
674 Cleanup thread stuff.
677 t....the threadobject
679 *******************************************************************************/
681 void threads_impl_thread_free(threadobject *t)
683 /* destroy the mutex and the condition */
685 if (pthread_mutex_destroy(&(t->waitmutex)) != 0)
686 vm_abort("threads_impl_thread_free: pthread_mutex_destroy failed: %s",
689 if (pthread_cond_destroy(&(t->waitcond)) != 0)
690 vm_abort("threads_impl_thread_free: pthread_cond_destroy failed: %s",
695 /* threads_get_current_threadobject ********************************************
697 Return the threadobject of the current thread.
700 the current threadobject *
702 *******************************************************************************/
704 threadobject *threads_get_current_threadobject(void)
710 /* threads_impl_preinit ********************************************************
712 Do some early initialization of stuff required.
714 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
715 is called AFTER this function!
717 *******************************************************************************/
719 void threads_impl_preinit(void)
721 pthread_mutex_init(&stopworldlock, NULL);
723 /* initialize exit mutex and condition (on exit we join all
726 pthread_mutex_init(&mutex_join, NULL);
727 pthread_cond_init(&cond_join, NULL);
729 #if !defined(HAVE___THREAD)
730 pthread_key_create(&threads_current_threadobject_key, NULL);
733 threads_sem_init(&suspend_ack, 0, 0);
737 /* threads_table_lock **********************************************************
739 Initialize threads table mutex.
741 *******************************************************************************/
743 void threads_impl_table_init(void)
745 pthread_mutex_init(&mutex_threads_table, NULL);
749 /* threads_table_lock **********************************************************
751 Enter the threads table mutex.
753 NOTE: We need this function as we can't use an internal lock for
754 the threads table because the thread's lock is initialized in
755 threads_table_add (when we have the thread index), but we
756 already need the lock at the entry of the function.
758 *******************************************************************************/
760 void threads_table_lock(void)
762 if (pthread_mutex_lock(&mutex_threads_table) != 0)
763 vm_abort("threads_table_lock: pthread_mutex_lock failed: %s",
768 /* threads_table_unlock ********************************************************
770 Leave the threads table mutex.
772 *******************************************************************************/
774 void threads_table_unlock(void)
776 if (pthread_mutex_unlock(&mutex_threads_table) != 0)
777 vm_abort("threads_table_unlock: pthread_mutex_unlock failed: %s",
782 /* threads_init ****************************************************************
784 Initializes the threads required by the JVM: main, finalizer.
786 *******************************************************************************/
788 bool threads_init(void)
790 threadobject *mainthread;
791 java_objectheader *threadname;
793 java_objectheader *o;
795 #if defined(ENABLE_JAVASE)
796 java_lang_ThreadGroup *threadgroup;
800 #if defined(WITH_CLASSPATH_GNU)
801 java_lang_VMThread *vmt;
806 /* get methods we need in this file */
808 #if defined(WITH_CLASSPATH_GNU)
810 class_resolveclassmethod(class_java_lang_Thread,
812 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
813 class_java_lang_Thread,
817 class_resolveclassmethod(class_java_lang_Thread,
819 utf_new_char("(Ljava/lang/String;)V"),
820 class_java_lang_Thread,
824 if (method_thread_init == NULL)
827 /* Get the main-thread (NOTE: The main threads is always the first
828 thread in the table). */
830 mainthread = threads_table_first();
832 /* create a java.lang.Thread for the main thread */
834 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
839 /* set the object in the internal data structure */
841 mainthread->object = t;
843 #if defined(ENABLE_INTRP)
844 /* create interpreter stack */
847 MSET(intrp_main_stack, 0, u1, opt_stacksize);
848 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
852 threadname = javastring_new(utf_new_char("main"));
854 #if defined(ENABLE_JAVASE)
855 /* allocate and init ThreadGroup */
857 threadgroup = (java_lang_ThreadGroup *)
858 native_new_and_init(class_java_lang_ThreadGroup);
860 if (threadgroup == NULL)
864 #if defined(WITH_CLASSPATH_GNU)
865 /* create a java.lang.VMThread for the main thread */
867 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
875 vmt->vmdata = (java_lang_Object *) mainthread;
877 /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
878 o = (java_objectheader *) t;
880 (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
882 #elif defined(WITH_CLASSPATH_CLDC1_1)
885 t->vm_thread = (java_lang_Object *) mainthread;
887 /* call public Thread(String name) */
889 o = (java_objectheader *) t;
891 (void) vm_call_method(method_thread_init, o, threadname);
897 #if defined(ENABLE_JAVASE)
898 t->group = threadgroup;
900 /* add main thread to java.lang.ThreadGroup */
902 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
904 utf_java_lang_Thread__V,
905 class_java_lang_ThreadGroup,
908 o = (java_objectheader *) threadgroup;
910 (void) vm_call_method(m, o, t);
916 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
918 /* initialize the thread attribute object */
920 if (pthread_attr_init(&attr) != 0)
921 vm_abort("threads_init: pthread_attr_init failed: %s", strerror(errno));
923 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
924 vm_abort("threads_init: pthread_attr_setdetachstate failed: %s",
928 if (opt_verbosethreads) {
929 printf("[Starting thread ");
930 threads_thread_print_info(mainthread);
935 /* everything's ok */
941 /* threads_startup_thread ******************************************************
943 Thread startup function called by pthread_create.
945 Thread which have a startup.function != NULL are marked as internal
946 threads. All other threads are threated as normal Java threads.
948 NOTE: This function is not called directly by pthread_create. The Boehm GC
949 inserts its own GC_start_routine in between, which then calls
953 t............the argument passed to pthread_create, ie. a pointer to
954 a startupinfo struct. CAUTION: When the `psem` semaphore
955 is posted, the startupinfo struct becomes invalid! (It
956 is allocated on the stack of threads_start_thread.)
958 ******************************************************************************/
960 static void *threads_startup_thread(void *t)
962 startupinfo *startup;
963 threadobject *thread;
964 #if defined(WITH_CLASSPATH_GNU)
965 java_lang_VMThread *vmt;
970 java_objectheader *o;
971 functionptr function;
973 #if defined(ENABLE_INTRP)
974 u1 *intrp_thread_stack;
976 /* create interpreter stack */
979 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
980 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
983 intrp_thread_stack = NULL;
986 /* get passed startupinfo structure and the values in there */
989 t = NULL; /* make sure it's not used wrongly */
991 thread = startup->thread;
992 function = startup->function;
993 psem = startup->psem;
995 /* Seems like we've encountered a situation where thread->tid was
996 not set by pthread_create. We alleviate this problem by waiting
997 for pthread_create to return. */
999 threads_sem_wait(startup->psem_first);
1001 #if defined(__DARWIN__)
1002 thread->mach_thread = mach_thread_self();
1005 /* store the internal thread data-structure in the TSD */
1007 threads_set_current_threadobject(thread);
1009 /* thread is running */
1011 thread->state = THREAD_STATE_RUNNABLE;
1013 /* insert the thread into the threads table */
1015 threads_table_add(thread);
1017 /* tell threads_startup_thread that we registered ourselves */
1018 /* CAUTION: *startup becomes invalid with this! */
1021 threads_sem_post(psem);
1023 /* set our priority */
1025 threads_set_thread_priority(thread->tid, thread->object->priority);
1027 #if defined(ENABLE_INTRP)
1028 /* set interpreter stack */
1031 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1034 #if defined(ENABLE_JVMTI)
1035 /* fire thread start event */
1038 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1041 #if !defined(NDEBUG)
1042 if (opt_verbosethreads) {
1043 printf("[Starting thread ");
1044 threads_thread_print_info(thread);
1049 /* find and run the Thread.run()V method if no other function was passed */
1051 if (function == NULL) {
1052 #if defined(WITH_CLASSPATH_GNU)
1053 /* We need to start the run method of
1054 java.lang.VMThread. Since this is a final class, we can use
1055 the class object directly. */
1057 c = class_java_lang_VMThread;
1058 #elif defined(WITH_CLASSPATH_CLDC1_1)
1059 c = thread->object->header.vftbl->class;
1062 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1065 vm_abort("threads_startup_thread: run() method not found in class");
1067 /* set ThreadMXBean variables */
1069 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1070 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1072 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1073 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1074 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1075 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1077 #if defined(WITH_CLASSPATH_GNU)
1078 /* we need to start the run method of java.lang.VMThread */
1080 vmt = (java_lang_VMThread *) thread->object->vmThread;
1081 o = (java_objectheader *) vmt;
1083 #elif defined(WITH_CLASSPATH_CLDC1_1)
1084 o = (java_objectheader *) thread->object;
1087 /* run the thread */
1089 (void) vm_call_method(m, o);
1092 /* set ThreadMXBean variables */
1094 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1095 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1097 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1098 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1099 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1100 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1102 /* call passed function, e.g. finalizer_thread */
1107 #if !defined(NDEBUG)
1108 if (opt_verbosethreads) {
1109 printf("[Stopping thread ");
1110 threads_thread_print_info(thread);
1115 #if defined(ENABLE_JVMTI)
1116 /* fire thread end event */
1119 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1122 if (!threads_detach_thread(thread))
1123 vm_abort("threads_startup_thread: threads_detach_thread failed");
1125 /* set ThreadMXBean variables */
1127 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1133 /* threads_impl_thread_start ***************************************************
1135 Start a thread in the JVM. Both (vm internal and java) thread
1139 thread....the thread object
1140 f.........function to run in the new thread. NULL means that the
1141 "run" method of the object `t` should be called
1143 ******************************************************************************/
1145 void threads_impl_thread_start(threadobject *thread, functionptr f)
1149 pthread_attr_t attr;
1150 startupinfo startup;
1153 /* fill startupinfo structure passed by pthread_create to
1154 * threads_startup_thread */
1156 startup.thread = thread;
1157 startup.function = f; /* maybe we don't call Thread.run()V */
1158 startup.psem = &sem;
1159 startup.psem_first = &sem_first;
1161 threads_sem_init(&sem, 0, 0);
1162 threads_sem_init(&sem_first, 0, 0);
1164 /* initialize thread attributes */
1166 if (pthread_attr_init(&attr) != 0)
1167 vm_abort("threads_impl_thread_start: pthread_attr_init failed: %s",
1170 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
1171 vm_abort("threads_impl_thread_start: pthread_attr_setdetachstate failed: %s",
1174 /* initialize thread stacksize */
1176 if (pthread_attr_setstacksize(&attr, opt_stacksize))
1177 vm_abort("threads_impl_thread_start: pthread_attr_setstacksize failed: %s",
1180 /* create the thread */
1182 ret = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1184 /* destroy the thread attributes */
1186 if (pthread_attr_destroy(&attr) != 0)
1187 vm_abort("threads_impl_thread_start: pthread_attr_destroy failed: %s",
1190 /* check for pthread_create error */
1193 vm_abort("threads_impl_thread_start: pthread_create failed: %s",
1196 /* signal that pthread_create has returned, so thread->tid is valid */
1198 threads_sem_post(&sem_first);
1200 /* wait here until the thread has entered itself into the thread list */
1202 threads_sem_wait(&sem);
1207 sem_destroy(&sem_first);
1211 /* threads_set_thread_priority *************************************************
1213 Set the priority of the given thread.
1216 tid..........thread id
1217 priority.....priority to set
1219 ******************************************************************************/
1221 void threads_set_thread_priority(pthread_t tid, int priority)
1223 struct sched_param schedp;
1226 pthread_getschedparam(tid, &policy, &schedp);
1227 schedp.sched_priority = priority;
1228 pthread_setschedparam(tid, policy, &schedp);
1232 /* threads_attach_current_thread ***********************************************
1234 Attaches the current thread to the VM. Used in JNI.
1236 *******************************************************************************/
1238 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
1240 threadobject *thread;
1242 java_objectheader *s;
1243 java_objectheader *o;
1244 java_lang_Thread *t;
1246 #if defined(ENABLE_JAVASE)
1247 java_lang_ThreadGroup *group;
1248 threadobject *mainthread;
1252 #if defined(WITH_CLASSPATH_GNU)
1253 java_lang_VMThread *vmt;
1256 /* create internal thread data-structure */
1258 thread = threads_thread_new();
1260 /* create a java.lang.Thread object */
1262 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
1269 /* thread is a Java thread and running */
1271 thread->flags = THREAD_FLAG_JAVA;
1274 thread->flags |= THREAD_FLAG_DAEMON;
1276 thread->state = THREAD_STATE_RUNNABLE;
1278 /* insert the thread into the threads table */
1280 threads_table_add(thread);
1282 #if !defined(NDEBUG)
1283 if (opt_verbosethreads) {
1284 printf("[Attaching thread ");
1285 threads_thread_print_info(thread);
1290 #if defined(ENABLE_INTRP)
1291 /* create interpreter stack */
1294 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1295 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
1299 #if defined(WITH_CLASSPATH_GNU)
1300 /* create a java.lang.VMThread object */
1302 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
1307 /* set the thread */
1310 vmt->vmdata = (java_lang_Object *) thread;
1311 #elif defined(WITH_CLASSPATH_CLDC1_1)
1312 t->vm_thread = (java_lang_Object *) thread;
1315 if (vm_aargs != NULL) {
1316 u = utf_new_char(vm_aargs->name);
1317 #if defined(ENABLE_JAVASE)
1318 group = (java_lang_ThreadGroup *) vm_aargs->group;
1323 #if defined(ENABLE_JAVASE)
1324 /* get the main thread */
1326 mainthread = threads_table_first();
1327 group = mainthread->object->group;
1331 /* the the thread name */
1333 s = javastring_new(u);
1335 /* for convenience */
1337 o = (java_objectheader *) thread->object;
1339 #if defined(WITH_CLASSPATH_GNU)
1340 (void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
1342 #elif defined(WITH_CLASSPATH_CLDC1_1)
1343 (void) vm_call_method(method_thread_init, o, s);
1349 #if defined(ENABLE_JAVASE)
1350 /* store the thread group in the object */
1352 thread->object->group = group;
1354 /* add thread to given thread-group */
1356 m = class_resolveclassmethod(group->header.vftbl->class,
1358 utf_java_lang_Thread__V,
1359 class_java_lang_ThreadGroup,
1362 o = (java_objectheader *) group;
1364 (void) vm_call_method(m, o, t);
1374 /* threads_detach_thread *******************************************************
1376 Detaches the passed thread from the VM. Used in JNI.
1378 *******************************************************************************/
1380 bool threads_detach_thread(threadobject *thread)
1382 #if defined(ENABLE_JAVASE)
1383 java_lang_ThreadGroup *group;
1385 java_objectheader *o;
1386 java_lang_Thread *t;
1389 /* XXX implement uncaught exception stuff (like JamVM does) */
1391 #if defined(ENABLE_JAVASE)
1392 /* remove thread from the thread group */
1394 group = thread->object->group;
1396 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1398 if (group != NULL) {
1399 m = class_resolveclassmethod(group->header.vftbl->class,
1401 utf_java_lang_Thread__V,
1402 class_java_lang_ThreadGroup,
1408 o = (java_objectheader *) group;
1411 (void) vm_call_method(m, o, t);
1418 /* thread is terminated */
1420 thread->state = THREAD_STATE_TERMINATED;
1422 /* remove thread from the threads table */
1424 threads_table_remove(thread);
1426 #if !defined(NDEBUG)
1427 if (opt_verbosethreads) {
1428 printf("[Detaching thread ");
1429 threads_thread_print_info(thread);
1434 /* signal that this thread has finished */
1436 pthread_mutex_lock(&mutex_join);
1437 pthread_cond_signal(&cond_join);
1438 pthread_mutex_unlock(&mutex_join);
1440 /* free the vm internal thread object */
1442 threads_thread_free(thread);
1449 /* threads_suspend_thread ******************************************************
1451 Suspend the passed thread. Execution stops until the thread
1452 is explicitly resumend again.
1455 reason.....Reason for suspending this thread.
1457 *******************************************************************************/
1459 bool threads_suspend_thread(threadobject *thread, s4 reason)
1461 /* acquire the suspendmutex */
1462 pthread_mutex_lock(&(thread->suspendmutex));
1464 if (thread->suspended) {
1465 pthread_mutex_unlock(&(thread->suspendmutex));
1469 /* set the reason for the suspension */
1470 thread->suspend_reason = reason;
1472 /* send the suspend signal to the thread */
1473 assert(thread != THREADOBJECT);
1474 pthread_kill(thread->tid, SIGUSR1);
1476 /* REMEMBER: do not release the suspendmutex, this is done
1477 by the thread itself in threads_suspend_ack(). */
1483 /* threads_suspend_ack *********************************************************
1485 Acknowledges the suspension of the current thread.
1488 pc.....The PC where the thread suspended its execution.
1489 sp.....The SP before the thread suspended its execution.
1491 *******************************************************************************/
1493 void threads_suspend_ack(u1* pc, u1* sp)
1495 threadobject *thread;
1497 thread = THREADOBJECT;
1499 assert(thread->suspend_reason != 0);
1501 /* TODO: remember dump memory size */
1503 #if defined(ENABLE_GC_CACAO)
1504 /* inform the GC about the suspension */
1505 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1507 /* check if the GC wants to leave the thread running */
1508 if (!gc_suspend(thread, pc, sp)) {
1510 /* REMEMBER: we do not unlock the suspendmutex because the thread
1511 will suspend itself again at a later time */
1518 /* mark this thread as suspended and remember the PC */
1520 thread->suspended = true;
1522 /* if we are stopping the world, we should send a global ack */
1523 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1524 threads_sem_post(&suspend_ack);
1527 /* release the suspension mutex and wait till we are resumed */
1528 pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
1530 /* TODO: free dump memory */
1532 /* release the suspendmutex */
1533 pthread_mutex_unlock(&(thread->suspendmutex));
1537 /* threads_resume_thread *******************************************************
1539 Resumes the execution of the passed thread.
1541 *******************************************************************************/
1543 bool threads_resume_thread(threadobject *thread)
1545 /* acquire the suspendmutex */
1546 pthread_mutex_lock(&(thread->suspendmutex));
1548 if (!thread->suspended) {
1549 pthread_mutex_unlock(&(thread->suspendmutex));
1553 thread->suspended = false;
1555 /* tell everyone that the thread should resume */
1556 assert(thread != THREADOBJECT);
1557 pthread_cond_broadcast(&(thread->suspendcond));
1559 /* release the suspendmutex */
1560 pthread_mutex_unlock(&(thread->suspendmutex));
1565 /* threads_find_non_daemon_thread **********************************************
1567 Helper function used by threads_join_all_threads for finding
1568 non-daemon threads that are still running.
1570 *******************************************************************************/
1572 static threadobject *threads_find_non_daemon_thread(void)
1574 threadobject *thread;
1576 /* lock the thread list */
1578 pthread_mutex_lock(&threadlistlock);
1580 /* iterate over all threads */
1582 thread = mainthreadobj->next;
1584 while (thread != mainthreadobj) {
1585 if (!(thread->flags & THREAD_FLAG_DAEMON)) {
1586 /* unlock thread list */
1588 pthread_mutex_unlock(&threadlistlock);
1593 thread = thread->next;
1596 /* unlock thread list */
1598 pthread_mutex_unlock(&threadlistlock);
1604 /* threads_join_all_threads ****************************************************
1606 Join all non-daemon threads.
1608 *******************************************************************************/
1610 void threads_join_all_threads(void)
1612 threadobject *thread;
1614 /* get current thread */
1616 thread = THREADOBJECT;
1618 /* this thread is waiting for all non-daemon threads to exit */
1620 thread->state = THREAD_STATE_WAITING;
1622 /* enter join mutex */
1624 pthread_mutex_lock(&mutex_join);
1626 /* Wait for condition as long as we have non-daemon threads. We
1627 compare against 1 because the current (main thread) is also a
1628 non-daemon thread. */
1630 while (threads_table_get_non_daemons() > 1)
1631 pthread_cond_wait(&cond_join, &mutex_join);
1633 /* leave join mutex */
1635 pthread_mutex_unlock(&mutex_join);
1639 /* threads_timespec_earlier ****************************************************
1641 Return true if timespec tv1 is earlier than timespec tv2.
1644 tv1..........first timespec
1645 tv2..........second timespec
1648 true, if the first timespec is earlier
1650 *******************************************************************************/
1652 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1653 const struct timespec *tv2)
1655 return (tv1->tv_sec < tv2->tv_sec)
1657 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1661 /* threads_current_time_is_earlier_than ****************************************
1663 Check if the current time is earlier than the given timespec.
1666 tv...........the timespec to compare against
1669 true, if the current time is earlier
1671 *******************************************************************************/
1673 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1675 struct timeval tvnow;
1676 struct timespec tsnow;
1678 /* get current time */
1680 if (gettimeofday(&tvnow, NULL) != 0)
1681 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1683 /* convert it to a timespec */
1685 tsnow.tv_sec = tvnow.tv_sec;
1686 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1688 /* compare current time with the given timespec */
1690 return threads_timespec_earlier(&tsnow, tv);
1694 /* threads_wait_with_timeout ***************************************************
1696 Wait until the given point in time on a monitor until either
1697 we are notified, we are interrupted, or the time is up.
1700 t............the current thread
1701 wakeupTime...absolute (latest) wakeup time
1702 If both tv_sec and tv_nsec are zero, this function
1703 waits for an unlimited amount of time.
1706 true.........if the wait has been interrupted,
1707 false........if the wait was ended by notification or timeout
1709 *******************************************************************************/
1711 static bool threads_wait_with_timeout(threadobject *thread,
1712 struct timespec *wakeupTime)
1714 bool wasinterrupted;
1716 /* acquire the waitmutex */
1718 pthread_mutex_lock(&thread->waitmutex);
1720 /* mark us as sleeping */
1722 thread->sleeping = true;
1724 /* wait on waitcond */
1726 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1728 while (!thread->interrupted && !thread->signaled
1729 && threads_current_time_is_earlier_than(wakeupTime))
1731 thread->state = THREAD_STATE_TIMED_WAITING;
1733 pthread_cond_timedwait(&thread->waitcond, &thread->waitmutex,
1736 thread->state = THREAD_STATE_RUNNABLE;
1741 while (!thread->interrupted && !thread->signaled) {
1742 thread->state = THREAD_STATE_WAITING;
1744 pthread_cond_wait(&thread->waitcond, &thread->waitmutex);
1746 thread->state = THREAD_STATE_RUNNABLE;
1750 /* check if we were interrupted */
1752 wasinterrupted = thread->interrupted;
1754 /* reset all flags */
1756 thread->interrupted = false;
1757 thread->signaled = false;
1758 thread->sleeping = false;
1760 /* release the waitmutex */
1762 pthread_mutex_unlock(&thread->waitmutex);
1764 return wasinterrupted;
1768 /* threads_wait_with_timeout_relative ******************************************
1770 Wait for the given maximum amount of time on a monitor until either
1771 we are notified, we are interrupted, or the time is up.
1774 t............the current thread
1775 millis.......milliseconds to wait
1776 nanos........nanoseconds to wait
1779 true.........if the wait has been interrupted,
1780 false........if the wait was ended by notification or timeout
1782 *******************************************************************************/
1784 bool threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1787 struct timespec wakeupTime;
1789 /* calculate the the (latest) wakeup time */
1791 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1795 return threads_wait_with_timeout(thread, &wakeupTime);
1799 /* threads_calc_absolute_time **************************************************
1801 Calculate the absolute point in time a given number of ms and ns from now.
1804 millis............milliseconds from now
1805 nanos.............nanoseconds from now
1808 *tm...............receives the timespec of the absolute point in time
1810 *******************************************************************************/
1812 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1814 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1817 gettimeofday(&tv, NULL);
1818 tv.tv_sec += millis / 1000;
1820 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1821 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1822 tm->tv_nsec = nsec % 1000000000;
1831 /* threads_thread_interrupt ****************************************************
1833 Interrupt the given thread.
1835 The thread gets the "waitcond" signal and
1836 its interrupted flag is set to true.
1839 thread............the thread to interrupt
1841 *******************************************************************************/
1843 void threads_thread_interrupt(threadobject *thread)
1845 /* Signal the thread a "waitcond" and tell it that it has been
1848 pthread_mutex_lock(&thread->waitmutex);
1850 /* Interrupt blocking system call using a signal. */
1852 pthread_kill(thread->tid, SIGHUP);
1854 if (thread->sleeping)
1855 pthread_cond_signal(&thread->waitcond);
1857 thread->interrupted = true;
1859 pthread_mutex_unlock(&thread->waitmutex);
1863 /* threads_check_if_interrupted_and_reset **************************************
1865 Check if the current thread has been interrupted and reset the
1869 true, if the current thread had been interrupted
1871 *******************************************************************************/
1873 bool threads_check_if_interrupted_and_reset(void)
1875 threadobject *thread;
1878 thread = THREADOBJECT;
1880 /* get interrupted flag */
1882 intr = thread->interrupted;
1884 /* reset interrupted flag */
1886 thread->interrupted = false;
1892 /* threads_thread_has_been_interrupted *****************************************
1894 Check if the given thread has been interrupted
1897 t............the thread to check
1900 true, if the given thread had been interrupted
1902 *******************************************************************************/
1904 bool threads_thread_has_been_interrupted(threadobject *thread)
1906 return thread->interrupted;
1910 /* threads_sleep ***************************************************************
1912 Sleep the current thread for the specified amount of time.
1914 *******************************************************************************/
1916 void threads_sleep(s8 millis, s4 nanos)
1918 threadobject *thread;
1919 struct timespec wakeupTime;
1920 bool wasinterrupted;
1922 thread = THREADOBJECT;
1924 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1926 wasinterrupted = threads_wait_with_timeout(thread, &wakeupTime);
1929 exceptions_throw_interruptedexception();
1933 /* threads_yield ***************************************************************
1935 Yield to the scheduler.
1937 *******************************************************************************/
1939 void threads_yield(void)
1946 * These are local overrides for various environment variables in Emacs.
1947 * Please do not remove this and leave it at the end of the file, where
1948 * Emacs will automagically detect them.
1949 * ---------------------------------------------------------------------
1952 * indent-tabs-mode: t
1956 * vim:noexpandtab:sw=4:ts=4: