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 8003 2007-06-03 18:42:09Z twisti $
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_list;
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 /* XXX We disable that whole bunch of code until we have the exact-GC
244 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
246 static volatile int stopworldwhere;
248 /* semaphore used for acknowleding thread suspension */
249 static sem_t suspend_ack;
250 #if defined(__MIPS__)
251 static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
252 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
257 /* mutexes used by the fake atomic instructions */
258 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
259 pthread_mutex_t _atomic_add_lock = PTHREAD_MUTEX_INITIALIZER;
260 pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
261 pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
265 /* threads_sem_init ************************************************************
267 Initialize a semaphore. Checks against errors and interruptions.
270 sem..............the semaphore to initialize
271 shared...........true if this semaphore will be shared between processes
272 value............the initial value for the semaphore
274 *******************************************************************************/
276 void threads_sem_init(sem_t *sem, bool shared, int value)
283 r = sem_init(sem, shared, value);
286 } while (errno == EINTR);
288 vm_abort("sem_init failed: %s", strerror(errno));
292 /* threads_sem_wait ************************************************************
294 Wait for a semaphore, non-interruptible.
296 IMPORTANT: Always use this function instead of `sem_wait` directly, as
297 `sem_wait` may be interrupted by signals!
300 sem..............the semaphore to wait on
302 *******************************************************************************/
304 void threads_sem_wait(sem_t *sem)
314 } while (errno == EINTR);
316 vm_abort("sem_wait failed: %s", strerror(errno));
320 /* threads_sem_post ************************************************************
322 Increase the count of a semaphore. Checks for errors.
325 sem..............the semaphore to increase the count of
327 *******************************************************************************/
329 void threads_sem_post(sem_t *sem)
335 /* unlike sem_wait, sem_post is not interruptible */
341 vm_abort("sem_post failed: %s", strerror(errno));
345 /* lock_stopworld **************************************************************
347 Enter the stopworld lock, specifying why the world shall be stopped.
350 where........ STOPWORLD_FROM_GC (1) from within GC
351 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
353 ******************************************************************************/
355 void lock_stopworld(int where)
357 pthread_mutex_lock(&stopworldlock);
358 /* stopworldwhere = where; */
362 /* unlock_stopworld ************************************************************
364 Release the stopworld lock.
366 ******************************************************************************/
368 void unlock_stopworld(void)
370 /* stopworldwhere = 0; */
371 pthread_mutex_unlock(&stopworldlock);
374 /* XXX We disable that whole bunch of code until we have the exact-GC
379 #if !defined(__DARWIN__)
380 /* Caller must hold threadlistlock */
381 static s4 threads_cast_sendsignals(s4 sig)
389 /* iterate over all started threads */
393 for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
394 /* don't send the signal to ourself */
399 /* don't send the signal to NEW threads (because they are not
400 completely initialized) */
402 if (t->state == THREAD_STATE_NEW)
405 /* send the signal */
407 pthread_kill(t->tid, sig);
409 /* increase threads count */
419 static void threads_cast_darwinstop(void)
421 threadobject *tobj = mainthreadobj;
422 threadobject *self = THREADOBJECT;
427 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
428 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
429 #if defined(__I386__)
430 i386_thread_state_t thread_state;
432 ppc_thread_state_t thread_state;
434 mach_port_t thread = tobj->mach_thread;
437 r = thread_suspend(thread);
439 if (r != KERN_SUCCESS)
440 vm_abort("thread_suspend failed");
442 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
443 &thread_state_count);
445 if (r != KERN_SUCCESS)
446 vm_abort("thread_get_state failed");
448 md_critical_section_restart((ucontext_t *) &thread_state);
450 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
453 if (r != KERN_SUCCESS)
454 vm_abort("thread_set_state failed");
458 } while (tobj != mainthreadobj);
461 static void threads_cast_darwinresume(void)
463 threadobject *tobj = mainthreadobj;
464 threadobject *self = THREADOBJECT;
469 mach_port_t thread = tobj->mach_thread;
472 r = thread_resume(thread);
474 if (r != KERN_SUCCESS)
475 vm_abort("thread_resume failed");
479 } while (tobj != mainthreadobj);
484 #if defined(__MIPS__)
485 static void threads_cast_irixresume(void)
487 pthread_mutex_lock(&suspend_ack_lock);
488 pthread_cond_broadcast(&suspend_cond);
489 pthread_mutex_unlock(&suspend_ack_lock);
493 #if !defined(DISABLE_GC)
495 void threads_cast_stopworld(void)
497 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
501 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
503 /* lock the threads lists */
507 #if defined(__DARWIN__)
508 threads_cast_darwinstop();
509 #elif defined(__CYGWIN__)
513 /* send all threads the suspend signal */
515 count = threads_cast_sendsignals(GC_signum1());
517 /* wait for all threads signaled to suspend */
519 for (i = 0; i < count; i++)
520 threads_sem_wait(&suspend_ack);
523 /* ATTENTION: Don't unlock the threads-lists here so that
524 non-signaled NEW threads can't change their state and execute
529 void threads_cast_startworld(void)
531 #if defined(__DARWIN__)
532 threads_cast_darwinresume();
533 #elif defined(__MIPS__)
534 threads_cast_irixresume();
535 #elif defined(__CYGWIN__)
539 (void) threads_cast_sendsignals(GC_signum2());
542 /* unlock the threads lists */
544 threads_list_unlock();
550 #if !defined(__DARWIN__)
551 static void threads_sigsuspend_handler(ucontext_t *_uc)
556 /* XXX TWISTI: this is just a quick hack */
557 #if defined(ENABLE_JIT)
558 md_critical_section_restart(_uc);
561 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
562 (not POSIX async-safe). */
563 #if defined(__IRIX__)
564 pthread_mutex_lock(&suspend_ack_lock);
565 threads_sem_post(&suspend_ack);
566 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
567 pthread_mutex_unlock(&suspend_ack_lock);
568 #elif defined(__CYGWIN__)
572 threads_sem_post(&suspend_ack);
576 sigdelset(&sigs, sig);
584 /* This function is called from Boehm GC code. */
586 int cacao_suspendhandler(ucontext_t *_uc)
588 if (stopworldwhere != STOPWORLD_FROM_CLASS_NUMBERING)
591 threads_sigsuspend_handler(_uc);
595 #endif /* DISABLE_GC */
600 /* threads_set_current_threadobject ********************************************
602 Set the current thread object.
605 thread.......the thread object to set
607 *******************************************************************************/
609 void threads_set_current_threadobject(threadobject *thread)
611 #if !defined(HAVE___THREAD)
612 if (pthread_setspecific(threads_current_threadobject_key, thread) != 0)
613 vm_abort("threads_set_current_threadobject: pthread_setspecific failed: %s", strerror(errno));
615 threads_current_threadobject = thread;
620 /* threads_impl_thread_new *****************************************************
622 Initialize implementation fields of a threadobject.
625 t....the threadobject
627 *******************************************************************************/
629 void threads_impl_thread_new(threadobject *t)
631 /* get the pthread id */
633 t->tid = pthread_self();
635 /* initialize the mutex and the condition */
637 pthread_mutex_init(&(t->waitmutex), NULL);
638 pthread_cond_init(&(t->waitcond), NULL);
640 #if defined(ENABLE_DEBUG_FILTER)
641 /* Initialize filter counters */
642 t->filterverbosecallctr[0] = 0;
643 t->filterverbosecallctr[1] = 0;
648 /* threads_impl_thread_free ****************************************************
650 Cleanup thread stuff.
653 t....the threadobject
655 *******************************************************************************/
657 void threads_impl_thread_free(threadobject *t)
659 /* destroy the mutex and the condition */
661 if (pthread_mutex_destroy(&(t->waitmutex)) != 0)
662 vm_abort("threads_impl_thread_free: pthread_mutex_destroy failed: %s",
665 if (pthread_cond_destroy(&(t->waitcond)) != 0)
666 vm_abort("threads_impl_thread_free: pthread_cond_destroy failed: %s",
671 /* threads_get_current_threadobject ********************************************
673 Return the threadobject of the current thread.
676 the current threadobject * (an instance of java.lang.Thread)
678 *******************************************************************************/
680 threadobject *threads_get_current_threadobject(void)
686 /* threads_impl_preinit ********************************************************
688 Do some early initialization of stuff required.
690 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
691 is called AFTER this function!
693 *******************************************************************************/
695 void threads_impl_preinit(void)
697 pthread_mutex_init(&stopworldlock, NULL);
699 /* initialize exit mutex and condition (on exit we join all
702 pthread_mutex_init(&mutex_join, NULL);
703 pthread_cond_init(&cond_join, NULL);
705 /* initialize the threads-list mutex */
707 pthread_mutex_init(&mutex_threads_list, NULL);
709 #if !defined(HAVE___THREAD)
710 pthread_key_create(&threads_current_threadobject_key, NULL);
713 /* threads_sem_init(&suspend_ack, 0, 0); */
717 /* threads_list_lock ***********************************************************
719 Enter the threads table mutex.
721 NOTE: We need this function as we can't use an internal lock for
722 the threads lists because the thread's lock is initialized in
723 threads_table_add (when we have the thread index), but we
724 already need the lock at the entry of the function.
726 *******************************************************************************/
728 void threads_list_lock(void)
730 if (pthread_mutex_lock(&mutex_threads_list) != 0)
731 vm_abort("threads_list_lock: pthread_mutex_lock failed: %s",
736 /* threads_list_unlock *********************************************************
738 Leave the threads list mutex.
740 *******************************************************************************/
742 void threads_list_unlock(void)
744 if (pthread_mutex_unlock(&mutex_threads_list) != 0)
745 vm_abort("threads_list_unlock: pthread_mutex_unlock failed: %s",
750 /* threads_mutex_join_lock *****************************************************
752 Enter the join mutex.
754 *******************************************************************************/
756 void threads_mutex_join_lock(void)
758 if (pthread_mutex_lock(&mutex_join) != 0)
759 vm_abort("threads_mutex_join_lock: pthread_mutex_lock failed: %s",
764 /* threads_mutex_join_unlock ***************************************************
766 Leave the join mutex.
768 *******************************************************************************/
770 void threads_mutex_join_unlock(void)
772 if (pthread_mutex_unlock(&mutex_join) != 0)
773 vm_abort("threads_mutex_join_unlock: pthread_mutex_unlock failed: %s",
778 /* threads_init ****************************************************************
780 Initializes the threads required by the JVM: main, finalizer.
782 *******************************************************************************/
784 bool threads_init(void)
786 threadobject *mainthread;
787 java_objectheader *threadname;
789 java_objectheader *o;
791 #if defined(ENABLE_JAVASE)
792 java_lang_ThreadGroup *threadgroup;
796 #if defined(WITH_CLASSPATH_GNU)
797 java_lang_VMThread *vmt;
802 /* get methods we need in this file */
804 #if defined(WITH_CLASSPATH_GNU)
806 class_resolveclassmethod(class_java_lang_Thread,
808 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
809 class_java_lang_Thread,
813 class_resolveclassmethod(class_java_lang_Thread,
815 utf_new_char("(Ljava/lang/String;)V"),
816 class_java_lang_Thread,
820 if (method_thread_init == NULL)
823 /* Get the main-thread (NOTE: The main threads is always the first
824 thread in the list). */
826 mainthread = threads_list_first();
828 /* create a java.lang.Thread for the main thread */
830 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
835 /* set the object in the internal data structure */
837 mainthread->object = t;
839 #if defined(ENABLE_INTRP)
840 /* create interpreter stack */
843 MSET(intrp_main_stack, 0, u1, opt_stacksize);
844 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
848 threadname = javastring_new(utf_new_char("main"));
850 #if defined(ENABLE_JAVASE)
851 /* allocate and init ThreadGroup */
853 threadgroup = (java_lang_ThreadGroup *)
854 native_new_and_init(class_java_lang_ThreadGroup);
856 if (threadgroup == NULL)
860 #if defined(WITH_CLASSPATH_GNU)
861 /* create a java.lang.VMThread for the main thread */
863 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
871 vmt->vmdata = (java_lang_Object *) mainthread;
873 /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
874 o = (java_objectheader *) t;
876 (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
878 #elif defined(WITH_CLASSPATH_CLDC1_1)
881 t->vm_thread = (java_lang_Object *) mainthread;
883 /* call public Thread(String name) */
885 o = (java_objectheader *) t;
887 (void) vm_call_method(method_thread_init, o, threadname);
893 #if defined(ENABLE_JAVASE)
894 t->group = threadgroup;
896 /* add main thread to java.lang.ThreadGroup */
898 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
900 utf_java_lang_Thread__V,
901 class_java_lang_ThreadGroup,
904 o = (java_objectheader *) threadgroup;
906 (void) vm_call_method(m, o, t);
912 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
914 /* initialize the thread attribute object */
916 if (pthread_attr_init(&attr) != 0)
917 vm_abort("threads_init: pthread_attr_init failed: %s", strerror(errno));
919 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
920 vm_abort("threads_init: pthread_attr_setdetachstate failed: %s",
924 if (opt_verbosethreads) {
925 printf("[Starting thread ");
926 threads_thread_print_info(mainthread);
931 /* everything's ok */
937 /* threads_startup_thread ******************************************************
939 Thread startup function called by pthread_create.
941 Thread which have a startup.function != NULL are marked as internal
942 threads. All other threads are threated as normal Java threads.
944 NOTE: This function is not called directly by pthread_create. The Boehm GC
945 inserts its own GC_start_routine in between, which then calls
949 arg..........the argument passed to pthread_create, ie. a pointer to
950 a startupinfo struct. CAUTION: When the `psem` semaphore
951 is posted, the startupinfo struct becomes invalid! (It
952 is allocated on the stack of threads_start_thread.)
954 ******************************************************************************/
956 static void *threads_startup_thread(void *arg)
958 startupinfo *startup;
959 threadobject *thread;
960 #if defined(WITH_CLASSPATH_GNU)
961 java_lang_VMThread *vmt;
966 java_objectheader *o;
967 functionptr function;
969 #if defined(ENABLE_INTRP)
970 u1 *intrp_thread_stack;
972 /* create interpreter stack */
975 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
976 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
979 intrp_thread_stack = NULL;
982 /* get passed startupinfo structure and the values in there */
986 thread = startup->thread;
987 function = startup->function;
988 psem = startup->psem;
990 /* Seems like we've encountered a situation where thread->tid was
991 not set by pthread_create. We alleviate this problem by waiting
992 for pthread_create to return. */
994 threads_sem_wait(startup->psem_first);
996 #if defined(__DARWIN__)
997 thread->mach_thread = mach_thread_self();
1000 /* store the internal thread data-structure in the TSD */
1002 threads_set_current_threadobject(thread);
1004 /* set our priority */
1006 threads_set_thread_priority(thread->tid, thread->object->priority);
1008 /* thread is completely initialized */
1010 threads_thread_state_runnable(thread);
1012 /* tell threads_startup_thread that we registered ourselves */
1013 /* CAUTION: *startup becomes invalid with this! */
1016 threads_sem_post(psem);
1018 #if defined(ENABLE_INTRP)
1019 /* set interpreter stack */
1022 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1025 #if defined(ENABLE_JVMTI)
1026 /* fire thread start event */
1029 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1032 #if !defined(NDEBUG)
1033 if (opt_verbosethreads) {
1034 printf("[Starting thread ");
1035 threads_thread_print_info(thread);
1040 /* find and run the Thread.run()V method if no other function was passed */
1042 if (function == NULL) {
1043 #if defined(WITH_CLASSPATH_GNU)
1044 /* We need to start the run method of
1045 java.lang.VMThread. Since this is a final class, we can use
1046 the class object directly. */
1048 c = class_java_lang_VMThread;
1049 #elif defined(WITH_CLASSPATH_CLDC1_1)
1050 c = thread->object->header.vftbl->class;
1053 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1056 vm_abort("threads_startup_thread: run() method not found in class");
1058 /* set ThreadMXBean variables */
1060 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1061 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1063 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1064 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1065 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1066 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1068 #if defined(WITH_CLASSPATH_GNU)
1069 /* we need to start the run method of java.lang.VMThread */
1071 vmt = (java_lang_VMThread *) thread->object->vmThread;
1072 o = (java_objectheader *) vmt;
1074 #elif defined(WITH_CLASSPATH_CLDC1_1)
1075 o = (java_objectheader *) thread->object;
1078 /* run the thread */
1080 (void) vm_call_method(m, o);
1083 /* set ThreadMXBean variables */
1085 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1086 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1088 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1089 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1090 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1091 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1093 /* call passed function, e.g. finalizer_thread */
1098 #if !defined(NDEBUG)
1099 if (opt_verbosethreads) {
1100 printf("[Stopping thread ");
1101 threads_thread_print_info(thread);
1106 #if defined(ENABLE_JVMTI)
1107 /* fire thread end event */
1110 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1113 if (!threads_detach_thread(thread))
1114 vm_abort("threads_startup_thread: threads_detach_thread failed");
1116 /* set ThreadMXBean variables */
1118 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1124 /* threads_impl_thread_start ***************************************************
1126 Start a thread in the JVM. Both (vm internal and java) thread
1130 thread....the thread object
1131 f.........function to run in the new thread. NULL means that the
1132 "run" method of the object `t` should be called
1134 ******************************************************************************/
1136 void threads_impl_thread_start(threadobject *thread, functionptr f)
1140 pthread_attr_t attr;
1141 startupinfo startup;
1144 /* fill startupinfo structure passed by pthread_create to
1145 * threads_startup_thread */
1147 startup.thread = thread;
1148 startup.function = f; /* maybe we don't call Thread.run()V */
1149 startup.psem = &sem;
1150 startup.psem_first = &sem_first;
1152 threads_sem_init(&sem, 0, 0);
1153 threads_sem_init(&sem_first, 0, 0);
1155 /* initialize thread attributes */
1157 if (pthread_attr_init(&attr) != 0)
1158 vm_abort("threads_impl_thread_start: pthread_attr_init failed: %s",
1161 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
1162 vm_abort("threads_impl_thread_start: pthread_attr_setdetachstate failed: %s",
1165 /* initialize thread stacksize */
1167 if (pthread_attr_setstacksize(&attr, opt_stacksize))
1168 vm_abort("threads_impl_thread_start: pthread_attr_setstacksize failed: %s",
1171 /* create the thread */
1173 ret = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1175 /* destroy the thread attributes */
1177 if (pthread_attr_destroy(&attr) != 0)
1178 vm_abort("threads_impl_thread_start: pthread_attr_destroy failed: %s",
1181 /* check for pthread_create error */
1184 vm_abort("threads_impl_thread_start: pthread_create failed: %s",
1187 /* signal that pthread_create has returned, so thread->tid is valid */
1189 threads_sem_post(&sem_first);
1191 /* wait here until the thread has entered itself into the thread list */
1193 threads_sem_wait(&sem);
1198 sem_destroy(&sem_first);
1202 /* threads_set_thread_priority *************************************************
1204 Set the priority of the given thread.
1207 tid..........thread id
1208 priority.....priority to set
1210 ******************************************************************************/
1212 void threads_set_thread_priority(pthread_t tid, int priority)
1214 struct sched_param schedp;
1217 pthread_getschedparam(tid, &policy, &schedp);
1218 schedp.sched_priority = priority;
1219 pthread_setschedparam(tid, policy, &schedp);
1223 /* threads_attach_current_thread ***********************************************
1225 Attaches the current thread to the VM. Used in JNI.
1227 *******************************************************************************/
1229 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
1231 threadobject *thread;
1233 java_objectheader *s;
1234 java_objectheader *o;
1235 java_lang_Thread *t;
1237 #if defined(ENABLE_JAVASE)
1238 java_lang_ThreadGroup *group;
1239 threadobject *mainthread;
1243 #if defined(WITH_CLASSPATH_GNU)
1244 java_lang_VMThread *vmt;
1247 /* Enter the join-mutex, so if the main-thread is currently
1248 waiting to join all threads, the number of non-daemon threads
1251 threads_mutex_join_lock();
1253 /* create internal thread data-structure */
1255 thread = threads_thread_new();
1257 /* thread is a Java thread and running */
1259 thread->flags = THREAD_FLAG_JAVA;
1262 thread->flags |= THREAD_FLAG_DAEMON;
1264 /* The thread is flagged and (non-)daemon thread, we can leave the
1267 threads_mutex_join_unlock();
1269 /* create a java.lang.Thread object */
1271 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
1273 /* XXX memory leak!!! */
1279 /* thread is completely initialized */
1281 threads_thread_state_runnable(thread);
1283 #if !defined(NDEBUG)
1284 if (opt_verbosethreads) {
1285 printf("[Attaching thread ");
1286 threads_thread_print_info(thread);
1291 #if defined(ENABLE_INTRP)
1292 /* create interpreter stack */
1295 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1296 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
1300 #if defined(WITH_CLASSPATH_GNU)
1301 /* create a java.lang.VMThread object */
1303 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
1305 /* XXX memory leak!!! */
1309 /* set the thread */
1312 vmt->vmdata = (java_lang_Object *) thread;
1313 #elif defined(WITH_CLASSPATH_CLDC1_1)
1314 t->vm_thread = (java_lang_Object *) thread;
1317 if (vm_aargs != NULL) {
1318 u = utf_new_char(vm_aargs->name);
1319 #if defined(ENABLE_JAVASE)
1320 group = (java_lang_ThreadGroup *) vm_aargs->group;
1325 #if defined(ENABLE_JAVASE)
1326 /* get the main thread */
1328 mainthread = threads_list_first();
1329 group = mainthread->object->group;
1333 /* the the thread name */
1335 s = javastring_new(u);
1337 /* for convenience */
1339 o = (java_objectheader *) thread->object;
1341 #if defined(WITH_CLASSPATH_GNU)
1342 (void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
1344 #elif defined(WITH_CLASSPATH_CLDC1_1)
1345 (void) vm_call_method(method_thread_init, o, s);
1351 #if defined(ENABLE_JAVASE)
1352 /* store the thread group in the object */
1354 thread->object->group = group;
1356 /* add thread to given thread-group */
1358 m = class_resolveclassmethod(group->header.vftbl->class,
1360 utf_java_lang_Thread__V,
1361 class_java_lang_ThreadGroup,
1364 o = (java_objectheader *) group;
1366 (void) vm_call_method(m, o, t);
1376 /* threads_detach_thread *******************************************************
1378 Detaches the passed thread from the VM. Used in JNI.
1380 *******************************************************************************/
1382 bool threads_detach_thread(threadobject *thread)
1384 #if defined(ENABLE_JAVASE)
1385 java_lang_ThreadGroup *group;
1387 java_objectheader *o;
1388 java_lang_Thread *t;
1391 /* XXX implement uncaught exception stuff (like JamVM does) */
1393 #if defined(ENABLE_JAVASE)
1394 /* remove thread from the thread group */
1396 group = thread->object->group;
1398 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1400 if (group != NULL) {
1401 m = class_resolveclassmethod(group->header.vftbl->class,
1403 utf_java_lang_Thread__V,
1404 class_java_lang_ThreadGroup,
1410 o = (java_objectheader *) group;
1413 (void) vm_call_method(m, o, t);
1420 /* thread is terminated */
1422 threads_thread_state_terminated(thread);
1424 #if !defined(NDEBUG)
1425 if (opt_verbosethreads) {
1426 printf("[Detaching thread ");
1427 threads_thread_print_info(thread);
1432 /* Enter the join-mutex before calling threads_thread_free, so
1433 threads_join_all_threads gets the correct number of non-daemon
1436 threads_mutex_join_lock();
1438 /* free the vm internal thread object */
1440 threads_thread_free(thread);
1442 /* Signal that this thread has finished and leave the mutex. */
1444 pthread_cond_signal(&cond_join);
1445 threads_mutex_join_unlock();
1451 /* threads_join_all_threads ****************************************************
1453 Join all non-daemon threads.
1455 *******************************************************************************/
1457 void threads_join_all_threads(void)
1461 /* get current thread */
1465 /* this thread is waiting for all non-daemon threads to exit */
1467 threads_thread_state_waiting(t);
1469 /* enter join mutex */
1471 threads_mutex_join_lock();
1473 /* Wait for condition as long as we have non-daemon threads. We
1474 compare against 1 because the current (main thread) is also a
1475 non-daemon thread. */
1477 while (threads_list_get_non_daemons() > 1)
1478 pthread_cond_wait(&cond_join, &mutex_join);
1480 /* leave join mutex */
1482 threads_mutex_join_unlock();
1486 /* threads_timespec_earlier ****************************************************
1488 Return true if timespec tv1 is earlier than timespec tv2.
1491 tv1..........first timespec
1492 tv2..........second timespec
1495 true, if the first timespec is earlier
1497 *******************************************************************************/
1499 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1500 const struct timespec *tv2)
1502 return (tv1->tv_sec < tv2->tv_sec)
1504 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1508 /* threads_current_time_is_earlier_than ****************************************
1510 Check if the current time is earlier than the given timespec.
1513 tv...........the timespec to compare against
1516 true, if the current time is earlier
1518 *******************************************************************************/
1520 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1522 struct timeval tvnow;
1523 struct timespec tsnow;
1525 /* get current time */
1527 if (gettimeofday(&tvnow, NULL) != 0)
1528 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1530 /* convert it to a timespec */
1532 tsnow.tv_sec = tvnow.tv_sec;
1533 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1535 /* compare current time with the given timespec */
1537 return threads_timespec_earlier(&tsnow, tv);
1541 /* threads_wait_with_timeout ***************************************************
1543 Wait until the given point in time on a monitor until either
1544 we are notified, we are interrupted, or the time is up.
1547 t............the current thread
1548 wakeupTime...absolute (latest) wakeup time
1549 If both tv_sec and tv_nsec are zero, this function
1550 waits for an unlimited amount of time.
1553 true.........if the wait has been interrupted,
1554 false........if the wait was ended by notification or timeout
1556 *******************************************************************************/
1558 static bool threads_wait_with_timeout(threadobject *thread,
1559 struct timespec *wakeupTime)
1561 bool wasinterrupted;
1563 /* acquire the waitmutex */
1565 pthread_mutex_lock(&thread->waitmutex);
1567 /* mark us as sleeping */
1569 thread->sleeping = true;
1571 /* wait on waitcond */
1573 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1575 while (!thread->interrupted && !thread->signaled
1576 && threads_current_time_is_earlier_than(wakeupTime))
1578 threads_thread_state_timed_waiting(thread);
1580 pthread_cond_timedwait(&thread->waitcond, &thread->waitmutex,
1583 threads_thread_state_runnable(thread);
1588 while (!thread->interrupted && !thread->signaled) {
1589 threads_thread_state_waiting(thread);
1591 pthread_cond_wait(&thread->waitcond, &thread->waitmutex);
1593 threads_thread_state_runnable(thread);
1597 /* check if we were interrupted */
1599 wasinterrupted = thread->interrupted;
1601 /* reset all flags */
1603 thread->interrupted = false;
1604 thread->signaled = false;
1605 thread->sleeping = false;
1607 /* release the waitmutex */
1609 pthread_mutex_unlock(&thread->waitmutex);
1611 return wasinterrupted;
1615 /* threads_wait_with_timeout_relative ******************************************
1617 Wait for the given maximum amount of time on a monitor until either
1618 we are notified, we are interrupted, or the time is up.
1621 t............the current thread
1622 millis.......milliseconds to wait
1623 nanos........nanoseconds to wait
1626 true.........if the wait has been interrupted,
1627 false........if the wait was ended by notification or timeout
1629 *******************************************************************************/
1631 bool threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1634 struct timespec wakeupTime;
1636 /* calculate the the (latest) wakeup time */
1638 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1642 return threads_wait_with_timeout(thread, &wakeupTime);
1646 /* threads_calc_absolute_time **************************************************
1648 Calculate the absolute point in time a given number of ms and ns from now.
1651 millis............milliseconds from now
1652 nanos.............nanoseconds from now
1655 *tm...............receives the timespec of the absolute point in time
1657 *******************************************************************************/
1659 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1661 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1664 gettimeofday(&tv, NULL);
1665 tv.tv_sec += millis / 1000;
1667 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1668 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1669 tm->tv_nsec = nsec % 1000000000;
1678 /* threads_thread_interrupt ****************************************************
1680 Interrupt the given thread.
1682 The thread gets the "waitcond" signal and
1683 its interrupted flag is set to true.
1686 thread............the thread to interrupt
1688 *******************************************************************************/
1690 void threads_thread_interrupt(threadobject *thread)
1692 /* Signal the thread a "waitcond" and tell it that it has been
1695 pthread_mutex_lock(&thread->waitmutex);
1697 /* Interrupt blocking system call using a signal. */
1699 pthread_kill(thread->tid, SIGHUP);
1701 if (thread->sleeping)
1702 pthread_cond_signal(&thread->waitcond);
1704 thread->interrupted = true;
1706 pthread_mutex_unlock(&thread->waitmutex);
1710 /* threads_check_if_interrupted_and_reset **************************************
1712 Check if the current thread has been interrupted and reset the
1716 true, if the current thread had been interrupted
1718 *******************************************************************************/
1720 bool threads_check_if_interrupted_and_reset(void)
1722 threadobject *thread;
1725 thread = THREADOBJECT;
1727 /* get interrupted flag */
1729 intr = thread->interrupted;
1731 /* reset interrupted flag */
1733 thread->interrupted = false;
1739 /* threads_thread_has_been_interrupted *****************************************
1741 Check if the given thread has been interrupted
1744 t............the thread to check
1747 true, if the given thread had been interrupted
1749 *******************************************************************************/
1751 bool threads_thread_has_been_interrupted(threadobject *thread)
1753 return thread->interrupted;
1757 /* threads_sleep ***************************************************************
1759 Sleep the current thread for the specified amount of time.
1761 *******************************************************************************/
1763 void threads_sleep(s8 millis, s4 nanos)
1765 threadobject *thread;
1766 struct timespec wakeupTime;
1767 bool wasinterrupted;
1769 thread = THREADOBJECT;
1771 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1773 wasinterrupted = threads_wait_with_timeout(thread, &wakeupTime);
1776 exceptions_throw_interruptedexception();
1780 /* threads_yield ***************************************************************
1782 Yield to the scheduler.
1784 *******************************************************************************/
1786 void threads_yield(void)
1793 * These are local overrides for various environment variables in Emacs.
1794 * Please do not remove this and leave it at the end of the file, where
1795 * Emacs will automagically detect them.
1796 * ---------------------------------------------------------------------
1799 * indent-tabs-mode: t
1803 * vim:noexpandtab:sw=4:ts=4: