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 8402 2007-08-22 19:32:27Z 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/llni.h"
61 #include "native/native.h"
62 #include "native/include/java_lang_Object.h"
63 #include "native/include/java_lang_String.h"
64 #include "native/include/java_lang_Throwable.h"
65 #include "native/include/java_lang_Thread.h"
67 #if defined(ENABLE_JAVASE)
68 # include "native/include/java_lang_ThreadGroup.h"
71 #if defined(WITH_CLASSPATH_GNU)
72 # include "native/include/java_lang_VMThread.h"
75 #include "threads/lock-common.h"
76 #include "threads/threads-common.h"
78 #include "threads/native/threads.h"
80 #include "toolbox/logging.h"
82 #include "vm/builtin.h"
83 #include "vm/exceptions.h"
84 #include "vm/global.h"
85 #include "vm/stringlocal.h"
88 #include "vm/jit/asmpart.h"
90 #include "vmcore/options.h"
92 #if defined(ENABLE_STATISTICS)
93 # include "vmcore/statistics.h"
96 #if !defined(__DARWIN__)
97 # if defined(__LINUX__)
98 # define GC_LINUX_THREADS
99 # elif defined(__MIPS__)
100 # define GC_IRIX_THREADS
102 # include <semaphore.h>
103 # if defined(ENABLE_GC_BOEHM)
104 # include "mm/boehm-gc/include/gc.h"
108 #if defined(ENABLE_JVMTI)
109 #include "native/jvmti/cacaodbg.h"
112 #if defined(__DARWIN__)
113 /* Darwin has no working semaphore implementation. This one is taken
117 This is a very simple semaphore implementation for darwin. It
118 is implemented in terms of pthreads calls so it isn't async signal
119 safe. This isn't a problem because signals aren't used to
120 suspend threads on darwin.
123 static int sem_init(sem_t *sem, int pshared, int value)
130 if (pthread_mutex_init(&sem->mutex, NULL) < 0)
133 if (pthread_cond_init(&sem->cond, NULL) < 0)
139 static int sem_post(sem_t *sem)
141 if (pthread_mutex_lock(&sem->mutex) < 0)
146 if (pthread_cond_signal(&sem->cond) < 0) {
147 pthread_mutex_unlock(&sem->mutex);
151 if (pthread_mutex_unlock(&sem->mutex) < 0)
157 static int sem_wait(sem_t *sem)
159 if (pthread_mutex_lock(&sem->mutex) < 0)
162 while (sem->value == 0) {
163 pthread_cond_wait(&sem->cond, &sem->mutex);
168 if (pthread_mutex_unlock(&sem->mutex) < 0)
174 static int sem_destroy(sem_t *sem)
176 if (pthread_cond_destroy(&sem->cond) < 0)
179 if (pthread_mutex_destroy(&sem->mutex) < 0)
184 #endif /* defined(__DARWIN__) */
187 /* internally used constants **************************************************/
189 /* CAUTION: Do not change these values. Boehm GC code depends on them. */
190 #define STOPWORLD_FROM_GC 1
191 #define STOPWORLD_FROM_CLASS_NUMBERING 2
194 /* startupinfo *****************************************************************
196 Struct used to pass info from threads_start_thread to
197 threads_startup_thread.
199 ******************************************************************************/
202 threadobject *thread; /* threadobject for this thread */
203 functionptr function; /* function to run in the new thread */
204 sem_t *psem; /* signals when thread has been entered */
205 /* in the thread list */
206 sem_t *psem_first; /* signals when pthread_create has returned */
210 /* prototypes *****************************************************************/
212 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
215 /******************************************************************************/
216 /* GLOBAL VARIABLES */
217 /******************************************************************************/
219 static methodinfo *method_thread_init;
221 /* the thread object of the current thread */
222 /* This is either a thread-local variable defined with __thread, or */
223 /* a thread-specific value stored with key threads_current_threadobject_key. */
224 #if defined(HAVE___THREAD)
225 __thread threadobject *threads_current_threadobject;
227 pthread_key_t threads_current_threadobject_key;
230 /* global mutex for the threads table */
231 static pthread_mutex_t mutex_threads_list;
233 /* global mutex for stop-the-world */
234 static pthread_mutex_t stopworldlock;
236 /* global mutex and condition for joining threads on exit */
237 static pthread_mutex_t mutex_join;
238 static pthread_cond_t cond_join;
240 /* XXX We disable that whole bunch of code until we have the exact-GC
245 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
247 static volatile int stopworldwhere;
249 /* semaphore used for acknowleding thread suspension */
250 static sem_t suspend_ack;
251 #if defined(__MIPS__)
252 static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
253 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
258 /* mutexes used by the fake atomic instructions */
259 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
260 pthread_mutex_t _atomic_add_lock = PTHREAD_MUTEX_INITIALIZER;
261 pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
262 pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
266 /* threads_sem_init ************************************************************
268 Initialize a semaphore. Checks against errors and interruptions.
271 sem..............the semaphore to initialize
272 shared...........true if this semaphore will be shared between processes
273 value............the initial value for the semaphore
275 *******************************************************************************/
277 void threads_sem_init(sem_t *sem, bool shared, int value)
284 r = sem_init(sem, shared, value);
287 } while (errno == EINTR);
289 vm_abort("sem_init failed: %s", strerror(errno));
293 /* threads_sem_wait ************************************************************
295 Wait for a semaphore, non-interruptible.
297 IMPORTANT: Always use this function instead of `sem_wait` directly, as
298 `sem_wait` may be interrupted by signals!
301 sem..............the semaphore to wait on
303 *******************************************************************************/
305 void threads_sem_wait(sem_t *sem)
315 } while (errno == EINTR);
317 vm_abort("sem_wait failed: %s", strerror(errno));
321 /* threads_sem_post ************************************************************
323 Increase the count of a semaphore. Checks for errors.
326 sem..............the semaphore to increase the count of
328 *******************************************************************************/
330 void threads_sem_post(sem_t *sem)
336 /* unlike sem_wait, sem_post is not interruptible */
342 vm_abort("sem_post failed: %s", strerror(errno));
346 /* lock_stopworld **************************************************************
348 Enter the stopworld lock, specifying why the world shall be stopped.
351 where........ STOPWORLD_FROM_GC (1) from within GC
352 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
354 ******************************************************************************/
356 void lock_stopworld(int where)
358 pthread_mutex_lock(&stopworldlock);
359 /* stopworldwhere = where; */
363 /* unlock_stopworld ************************************************************
365 Release the stopworld lock.
367 ******************************************************************************/
369 void unlock_stopworld(void)
371 /* stopworldwhere = 0; */
372 pthread_mutex_unlock(&stopworldlock);
375 /* XXX We disable that whole bunch of code until we have the exact-GC
380 #if !defined(__DARWIN__)
381 /* Caller must hold threadlistlock */
382 static s4 threads_cast_sendsignals(s4 sig)
390 /* iterate over all started threads */
394 for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
395 /* don't send the signal to ourself */
400 /* don't send the signal to NEW threads (because they are not
401 completely initialized) */
403 if (t->state == THREAD_STATE_NEW)
406 /* send the signal */
408 pthread_kill(t->tid, sig);
410 /* increase threads count */
420 static void threads_cast_darwinstop(void)
422 threadobject *tobj = mainthreadobj;
423 threadobject *self = THREADOBJECT;
428 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
429 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
430 #if defined(__I386__)
431 i386_thread_state_t thread_state;
433 ppc_thread_state_t thread_state;
435 mach_port_t thread = tobj->mach_thread;
438 r = thread_suspend(thread);
440 if (r != KERN_SUCCESS)
441 vm_abort("thread_suspend failed");
443 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
444 &thread_state_count);
446 if (r != KERN_SUCCESS)
447 vm_abort("thread_get_state failed");
449 md_critical_section_restart((ucontext_t *) &thread_state);
451 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
454 if (r != KERN_SUCCESS)
455 vm_abort("thread_set_state failed");
459 } while (tobj != mainthreadobj);
462 static void threads_cast_darwinresume(void)
464 threadobject *tobj = mainthreadobj;
465 threadobject *self = THREADOBJECT;
470 mach_port_t thread = tobj->mach_thread;
473 r = thread_resume(thread);
475 if (r != KERN_SUCCESS)
476 vm_abort("thread_resume failed");
480 } while (tobj != mainthreadobj);
485 #if defined(__MIPS__)
486 static void threads_cast_irixresume(void)
488 pthread_mutex_lock(&suspend_ack_lock);
489 pthread_cond_broadcast(&suspend_cond);
490 pthread_mutex_unlock(&suspend_ack_lock);
494 #if !defined(DISABLE_GC)
496 void threads_cast_stopworld(void)
498 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
502 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
504 /* lock the threads lists */
508 #if defined(__DARWIN__)
509 threads_cast_darwinstop();
510 #elif defined(__CYGWIN__)
514 /* send all threads the suspend signal */
516 count = threads_cast_sendsignals(GC_signum1());
518 /* wait for all threads signaled to suspend */
520 for (i = 0; i < count; i++)
521 threads_sem_wait(&suspend_ack);
524 /* ATTENTION: Don't unlock the threads-lists here so that
525 non-signaled NEW threads can't change their state and execute
530 void threads_cast_startworld(void)
532 #if defined(__DARWIN__)
533 threads_cast_darwinresume();
534 #elif defined(__MIPS__)
535 threads_cast_irixresume();
536 #elif defined(__CYGWIN__)
540 (void) threads_cast_sendsignals(GC_signum2());
543 /* unlock the threads lists */
545 threads_list_unlock();
551 #if !defined(__DARWIN__)
552 static void threads_sigsuspend_handler(ucontext_t *_uc)
557 /* XXX TWISTI: this is just a quick hack */
558 #if defined(ENABLE_JIT)
559 md_critical_section_restart(_uc);
562 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
563 (not POSIX async-safe). */
564 #if defined(__IRIX__)
565 pthread_mutex_lock(&suspend_ack_lock);
566 threads_sem_post(&suspend_ack);
567 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
568 pthread_mutex_unlock(&suspend_ack_lock);
569 #elif defined(__CYGWIN__)
573 threads_sem_post(&suspend_ack);
577 sigdelset(&sigs, sig);
585 /* This function is called from Boehm GC code. */
587 int cacao_suspendhandler(ucontext_t *_uc)
589 if (stopworldwhere != STOPWORLD_FROM_CLASS_NUMBERING)
592 threads_sigsuspend_handler(_uc);
596 #endif /* DISABLE_GC */
601 /* threads_set_current_threadobject ********************************************
603 Set the current thread object.
606 thread.......the thread object to set
608 *******************************************************************************/
610 void threads_set_current_threadobject(threadobject *thread)
612 #if !defined(HAVE___THREAD)
613 if (pthread_setspecific(threads_current_threadobject_key, thread) != 0)
614 vm_abort("threads_set_current_threadobject: pthread_setspecific failed: %s", strerror(errno));
616 threads_current_threadobject = thread;
621 /* threads_impl_thread_new *****************************************************
623 Initialize implementation fields of a threadobject.
626 t....the threadobject
628 *******************************************************************************/
630 void threads_impl_thread_new(threadobject *t)
632 /* get the pthread id */
634 t->tid = pthread_self();
636 /* initialize the mutex and the condition */
638 pthread_mutex_init(&(t->waitmutex), NULL);
639 pthread_cond_init(&(t->waitcond), NULL);
641 #if defined(ENABLE_DEBUG_FILTER)
642 /* Initialize filter counters */
643 t->filterverbosecallctr[0] = 0;
644 t->filterverbosecallctr[1] = 0;
648 t->tracejavacallindent = 0;
649 t->tracejavacallcount = 0;
654 /* threads_impl_thread_free ****************************************************
656 Cleanup thread stuff.
659 t....the threadobject
661 *******************************************************************************/
663 void threads_impl_thread_free(threadobject *t)
665 /* destroy the mutex and the condition */
667 if (pthread_mutex_destroy(&(t->waitmutex)) != 0)
668 vm_abort("threads_impl_thread_free: pthread_mutex_destroy failed: %s",
671 if (pthread_cond_destroy(&(t->waitcond)) != 0)
672 vm_abort("threads_impl_thread_free: pthread_cond_destroy failed: %s",
677 /* threads_get_current_threadobject ********************************************
679 Return the threadobject of the current thread.
682 the current threadobject * (an instance of java.lang.Thread)
684 *******************************************************************************/
686 threadobject *threads_get_current_threadobject(void)
692 /* threads_impl_preinit ********************************************************
694 Do some early initialization of stuff required.
696 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
697 is called AFTER this function!
699 *******************************************************************************/
701 void threads_impl_preinit(void)
703 pthread_mutex_init(&stopworldlock, NULL);
705 /* initialize exit mutex and condition (on exit we join all
708 pthread_mutex_init(&mutex_join, NULL);
709 pthread_cond_init(&cond_join, NULL);
711 /* initialize the threads-list mutex */
713 pthread_mutex_init(&mutex_threads_list, NULL);
715 #if !defined(HAVE___THREAD)
716 pthread_key_create(&threads_current_threadobject_key, NULL);
719 /* threads_sem_init(&suspend_ack, 0, 0); */
723 /* threads_list_lock ***********************************************************
725 Enter the threads table mutex.
727 NOTE: We need this function as we can't use an internal lock for
728 the threads lists because the thread's lock is initialized in
729 threads_table_add (when we have the thread index), but we
730 already need the lock at the entry of the function.
732 *******************************************************************************/
734 void threads_list_lock(void)
736 if (pthread_mutex_lock(&mutex_threads_list) != 0)
737 vm_abort("threads_list_lock: pthread_mutex_lock failed: %s",
742 /* threads_list_unlock *********************************************************
744 Leave the threads list mutex.
746 *******************************************************************************/
748 void threads_list_unlock(void)
750 if (pthread_mutex_unlock(&mutex_threads_list) != 0)
751 vm_abort("threads_list_unlock: pthread_mutex_unlock failed: %s",
756 /* threads_mutex_join_lock *****************************************************
758 Enter the join mutex.
760 *******************************************************************************/
762 void threads_mutex_join_lock(void)
764 if (pthread_mutex_lock(&mutex_join) != 0)
765 vm_abort("threads_mutex_join_lock: pthread_mutex_lock failed: %s",
770 /* threads_mutex_join_unlock ***************************************************
772 Leave the join mutex.
774 *******************************************************************************/
776 void threads_mutex_join_unlock(void)
778 if (pthread_mutex_unlock(&mutex_join) != 0)
779 vm_abort("threads_mutex_join_unlock: pthread_mutex_unlock failed: %s",
784 /* threads_init ****************************************************************
786 Initializes the threads required by the JVM: main, finalizer.
788 *******************************************************************************/
790 bool threads_init(void)
792 threadobject *mainthread;
793 java_handle_t *threadname;
797 #if defined(ENABLE_JAVASE)
798 java_lang_ThreadGroup *threadgroup;
802 #if defined(WITH_CLASSPATH_GNU)
803 java_lang_VMThread *vmt;
808 /* get methods we need in this file */
810 #if defined(WITH_CLASSPATH_GNU)
812 class_resolveclassmethod(class_java_lang_Thread,
814 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
815 class_java_lang_Thread,
817 #elif defined(WITH_CLASSPATH_SUN)
819 class_resolveclassmethod(class_java_lang_Thread,
821 utf_new_char("(Ljava/lang/String;)V"),
822 class_java_lang_Thread,
824 #elif defined(WITH_CLASSPATH_CLDC1_1)
826 class_resolveclassmethod(class_java_lang_Thread,
828 utf_new_char("(Ljava/lang/String;)V"),
829 class_java_lang_Thread,
832 # error unknown classpath configuration
835 if (method_thread_init == NULL)
838 /* Get the main-thread (NOTE: The main threads is always the first
839 thread in the list). */
841 mainthread = threads_list_first();
843 /* create a java.lang.Thread for the main thread */
845 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
850 /* set the object in the internal data structure */
852 mainthread->object = t;
854 #if defined(ENABLE_INTRP)
855 /* create interpreter stack */
858 MSET(intrp_main_stack, 0, u1, opt_stacksize);
859 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
863 threadname = javastring_new(utf_new_char("main"));
865 #if defined(ENABLE_JAVASE)
866 /* allocate and init ThreadGroup */
868 threadgroup = (java_lang_ThreadGroup *)
869 native_new_and_init(class_java_lang_ThreadGroup);
871 if (threadgroup == NULL)
875 #if defined(WITH_CLASSPATH_GNU)
876 /* create a java.lang.VMThread for the main thread */
878 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
885 LLNI_field_set_ref(vmt, thread, t);
886 LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) mainthread);
888 /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
889 o = (java_handle_t *) t;
891 (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
894 #elif defined(WITH_CLASSPATH_SUN)
896 /* We trick java.lang.Thread.<init>, which sets the priority of
897 the current thread to the parent's one. */
899 t->priority = NORM_PRIORITY;
901 /* Call java.lang.Thread.<init>(Ljava/lang/String;)V */
903 o = (java_object_t *) t;
905 (void) vm_call_method(method_thread_init, o, threadname);
907 #elif defined(WITH_CLASSPATH_CLDC1_1)
911 t->vm_thread = (java_lang_Object *) mainthread;
913 /* call public Thread(String name) */
915 o = (java_handle_t *) t;
917 (void) vm_call_method(method_thread_init, o, threadname);
919 # error unknown classpath configuration
922 if (exceptions_get_exception())
925 #if defined(ENABLE_JAVASE)
926 LLNI_field_set_ref(t, group, threadgroup);
928 # if defined(WITH_CLASSPATH_GNU)
929 /* add main thread to java.lang.ThreadGroup */
931 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
933 utf_java_lang_Thread__V,
934 class_java_lang_ThreadGroup,
937 o = (java_handle_t *) threadgroup;
939 (void) vm_call_method(m, o, t);
941 if (exceptions_get_exception())
944 # warning Do not know what to do here
948 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
950 /* initialize the thread attribute object */
952 if (pthread_attr_init(&attr) != 0)
953 vm_abort("threads_init: pthread_attr_init failed: %s", strerror(errno));
955 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
956 vm_abort("threads_init: pthread_attr_setdetachstate failed: %s",
960 if (opt_verbosethreads) {
961 printf("[Starting thread ");
962 threads_thread_print_info(mainthread);
967 /* everything's ok */
973 /* threads_startup_thread ******************************************************
975 Thread startup function called by pthread_create.
977 Thread which have a startup.function != NULL are marked as internal
978 threads. All other threads are threated as normal Java threads.
980 NOTE: This function is not called directly by pthread_create. The Boehm GC
981 inserts its own GC_start_routine in between, which then calls
985 arg..........the argument passed to pthread_create, ie. a pointer to
986 a startupinfo struct. CAUTION: When the `psem` semaphore
987 is posted, the startupinfo struct becomes invalid! (It
988 is allocated on the stack of threads_start_thread.)
990 ******************************************************************************/
992 static void *threads_startup_thread(void *arg)
994 startupinfo *startup;
995 threadobject *thread;
996 #if defined(WITH_CLASSPATH_GNU)
997 java_lang_VMThread *vmt;
1003 functionptr function;
1005 #if defined(ENABLE_INTRP)
1006 u1 *intrp_thread_stack;
1008 /* create interpreter stack */
1011 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
1012 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
1015 intrp_thread_stack = NULL;
1018 /* get passed startupinfo structure and the values in there */
1022 thread = startup->thread;
1023 function = startup->function;
1024 psem = startup->psem;
1026 /* Seems like we've encountered a situation where thread->tid was
1027 not set by pthread_create. We alleviate this problem by waiting
1028 for pthread_create to return. */
1030 threads_sem_wait(startup->psem_first);
1032 #if defined(__DARWIN__)
1033 thread->mach_thread = mach_thread_self();
1036 /* store the internal thread data-structure in the TSD */
1038 threads_set_current_threadobject(thread);
1040 /* set our priority */
1042 threads_set_thread_priority(thread->tid, LLNI_field_direct(thread->object, priority));
1044 /* thread is completely initialized */
1046 threads_thread_state_runnable(thread);
1048 /* tell threads_startup_thread that we registered ourselves */
1049 /* CAUTION: *startup becomes invalid with this! */
1052 threads_sem_post(psem);
1054 #if defined(ENABLE_INTRP)
1055 /* set interpreter stack */
1058 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1061 #if defined(ENABLE_JVMTI)
1062 /* fire thread start event */
1065 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1068 #if !defined(NDEBUG)
1069 if (opt_verbosethreads) {
1070 printf("[Starting thread ");
1071 threads_thread_print_info(thread);
1076 /* find and run the Thread.run()V method if no other function was passed */
1078 if (function == NULL) {
1079 #if defined(WITH_CLASSPATH_GNU)
1080 /* We need to start the run method of
1081 java.lang.VMThread. Since this is a final class, we can use
1082 the class object directly. */
1084 c = class_java_lang_VMThread;
1085 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
1086 c = thread->object->header.vftbl->class;
1088 # error unknown classpath configuration
1091 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1094 vm_abort("threads_startup_thread: run() method not found in class");
1096 /* set ThreadMXBean variables */
1098 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1099 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1101 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1102 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1103 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1104 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1106 #if defined(WITH_CLASSPATH_GNU)
1107 /* we need to start the run method of java.lang.VMThread */
1109 vmt = (java_lang_VMThread *) LLNI_field_direct(thread->object, vmThread);
1110 o = (java_handle_t *) vmt;
1112 #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
1113 o = (java_handle_t *) thread->object;
1115 # error unknown classpath configuration
1118 /* run the thread */
1120 (void) vm_call_method(m, o);
1123 /* set ThreadMXBean variables */
1125 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1126 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1128 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1129 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1130 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1131 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1133 /* call passed function, e.g. finalizer_thread */
1138 #if !defined(NDEBUG)
1139 if (opt_verbosethreads) {
1140 printf("[Stopping thread ");
1141 threads_thread_print_info(thread);
1146 #if defined(ENABLE_JVMTI)
1147 /* fire thread end event */
1150 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1153 /* We ignore the return value. */
1155 (void) threads_detach_thread(thread);
1157 /* set ThreadMXBean variables */
1159 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1165 /* threads_impl_thread_start ***************************************************
1167 Start a thread in the JVM. Both (vm internal and java) thread
1171 thread....the thread object
1172 f.........function to run in the new thread. NULL means that the
1173 "run" method of the object `t` should be called
1175 ******************************************************************************/
1177 void threads_impl_thread_start(threadobject *thread, functionptr f)
1181 pthread_attr_t attr;
1182 startupinfo startup;
1185 /* fill startupinfo structure passed by pthread_create to
1186 * threads_startup_thread */
1188 startup.thread = thread;
1189 startup.function = f; /* maybe we don't call Thread.run()V */
1190 startup.psem = &sem;
1191 startup.psem_first = &sem_first;
1193 threads_sem_init(&sem, 0, 0);
1194 threads_sem_init(&sem_first, 0, 0);
1196 /* initialize thread attributes */
1198 if (pthread_attr_init(&attr) != 0)
1199 vm_abort("threads_impl_thread_start: pthread_attr_init failed: %s",
1202 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
1203 vm_abort("threads_impl_thread_start: pthread_attr_setdetachstate failed: %s",
1206 /* initialize thread stacksize */
1208 if (pthread_attr_setstacksize(&attr, opt_stacksize))
1209 vm_abort("threads_impl_thread_start: pthread_attr_setstacksize failed: %s",
1212 /* create the thread */
1214 ret = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1216 /* destroy the thread attributes */
1218 if (pthread_attr_destroy(&attr) != 0)
1219 vm_abort("threads_impl_thread_start: pthread_attr_destroy failed: %s",
1222 /* check for pthread_create error */
1225 vm_abort("threads_impl_thread_start: pthread_create failed: %s",
1228 /* signal that pthread_create has returned, so thread->tid is valid */
1230 threads_sem_post(&sem_first);
1232 /* wait here until the thread has entered itself into the thread list */
1234 threads_sem_wait(&sem);
1239 sem_destroy(&sem_first);
1243 /* threads_set_thread_priority *************************************************
1245 Set the priority of the given thread.
1248 tid..........thread id
1249 priority.....priority to set
1251 ******************************************************************************/
1253 void threads_set_thread_priority(pthread_t tid, int priority)
1255 struct sched_param schedp;
1258 pthread_getschedparam(tid, &policy, &schedp);
1259 schedp.sched_priority = priority;
1260 pthread_setschedparam(tid, policy, &schedp);
1264 /* threads_attach_current_thread ***********************************************
1266 Attaches the current thread to the VM. Used in JNI.
1268 *******************************************************************************/
1270 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
1272 threadobject *thread;
1276 java_lang_Thread *t;
1278 #if defined(ENABLE_JAVASE)
1279 java_lang_ThreadGroup *group;
1280 threadobject *mainthread;
1285 #if defined(WITH_CLASSPATH_GNU)
1286 java_lang_VMThread *vmt;
1289 /* Enter the join-mutex, so if the main-thread is currently
1290 waiting to join all threads, the number of non-daemon threads
1293 threads_mutex_join_lock();
1295 /* create internal thread data-structure */
1297 thread = threads_thread_new();
1299 /* thread is a Java thread and running */
1301 thread->flags = THREAD_FLAG_JAVA;
1304 thread->flags |= THREAD_FLAG_DAEMON;
1306 /* The thread is flagged and (non-)daemon thread, we can leave the
1309 threads_mutex_join_unlock();
1311 /* create a java.lang.Thread object */
1313 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
1315 /* XXX memory leak!!! */
1321 /* thread is completely initialized */
1323 threads_thread_state_runnable(thread);
1325 #if !defined(NDEBUG)
1326 if (opt_verbosethreads) {
1327 printf("[Attaching thread ");
1328 threads_thread_print_info(thread);
1333 #if defined(ENABLE_INTRP)
1334 /* create interpreter stack */
1337 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1338 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
1342 #if defined(WITH_CLASSPATH_GNU)
1344 /* create a java.lang.VMThread object */
1346 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
1348 /* XXX memory leak!!! */
1352 /* set the thread */
1354 LLNI_field_set_ref(vmt, thread, t);
1355 LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) thread);
1357 #elif defined(WITH_CLASSPATH_SUN)
1359 vm_abort("threads_attach_current_thread: IMPLEMENT ME!");
1361 #elif defined(WITH_CLASSPATH_CLDC1_1)
1363 LLNI_field_set_val(t, vm_thread, (java_lang_Object *) thread);
1366 # error unknown classpath configuration
1369 if (vm_aargs != NULL) {
1370 u = utf_new_char(vm_aargs->name);
1371 #if defined(ENABLE_JAVASE)
1372 group = (java_lang_ThreadGroup *) vm_aargs->group;
1377 #if defined(ENABLE_JAVASE)
1378 /* get the main thread */
1380 mainthread = threads_list_first();
1381 group = LLNI_field_direct(mainthread->object, group);
1385 /* the the thread name */
1387 s = javastring_new(u);
1389 /* for convenience */
1391 o = (java_handle_t *) thread->object;
1393 #if defined(WITH_CLASSPATH_GNU)
1394 (void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
1396 #elif defined(WITH_CLASSPATH_CLDC1_1)
1397 (void) vm_call_method(method_thread_init, o, s);
1400 if (exceptions_get_exception())
1403 #if defined(ENABLE_JAVASE)
1404 /* store the thread group in the object */
1406 LLNI_field_direct(thread->object, group) = group;
1408 /* add thread to given thread-group */
1410 LLNI_class_get(group, c);
1412 m = class_resolveclassmethod(c,
1414 utf_java_lang_Thread__V,
1415 class_java_lang_ThreadGroup,
1418 o = (java_handle_t *) group;
1420 (void) vm_call_method(m, o, t);
1422 if (exceptions_get_exception())
1430 /* threads_detach_thread *******************************************************
1432 Detaches the passed thread from the VM. Used in JNI.
1434 *******************************************************************************/
1436 bool threads_detach_thread(threadobject *t)
1438 #if defined(ENABLE_JAVASE)
1439 java_lang_Thread *object;
1440 java_lang_ThreadGroup *group;
1442 java_lang_Object *handler;
1448 #if defined(ENABLE_JAVASE)
1451 group = LLNI_field_direct(object, group);
1453 /* If there's an uncaught exception, call uncaughtException on the
1454 thread's exception handler, or the thread's group if this is
1457 e = exceptions_get_and_clear_exception();
1460 /* We use a java_lang_Object here, as it's not trivial to
1461 build the java_lang_Thread_UncaughtExceptionHandler header
1464 # if defined(WITH_CLASSPATH_GNU)
1465 handler = (java_lang_Object *) LLNI_field_direct(object, exceptionHandler);
1466 # elif defined(WITH_CLASSPATH_SUN)
1467 handler = (java_lang_Object *) LLNI_field_direct(object, uncaughtExceptionHandler);
1470 if (handler != NULL) {
1471 LLNI_class_get(handler, c);
1472 o = (java_handle_t *) handler;
1475 LLNI_class_get(group, c);
1476 o = (java_handle_t *) group;
1479 m = class_resolveclassmethod(c,
1480 utf_uncaughtException,
1481 utf_java_lang_Thread_java_lang_Throwable__V,
1488 (void) vm_call_method(m, o, object, e);
1490 if (exceptions_get_exception())
1494 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1496 /* Remove thread from the thread group. */
1498 if (group != NULL) {
1499 LLNI_class_get(group, c);
1501 # if defined(WITH_CLASSPATH_GNU)
1502 m = class_resolveclassmethod(c,
1504 utf_java_lang_Thread__V,
1505 class_java_lang_ThreadGroup,
1507 # elif defined(WITH_CLASSPATH_SUN)
1508 m = class_resolveclassmethod(c,
1510 utf_java_lang_Thread__V,
1511 class_java_lang_ThreadGroup,
1514 # error unknown classpath configuration
1520 o = (java_handle_t *) group;
1522 (void) vm_call_method(m, o, object);
1524 if (exceptions_get_exception())
1529 /* thread is terminated */
1531 threads_thread_state_terminated(t);
1533 #if !defined(NDEBUG)
1534 if (opt_verbosethreads) {
1535 printf("[Detaching thread ");
1536 threads_thread_print_info(t);
1541 /* Enter the join-mutex before calling threads_thread_free, so
1542 threads_join_all_threads gets the correct number of non-daemon
1545 threads_mutex_join_lock();
1547 /* free the vm internal thread object */
1549 threads_thread_free(t);
1551 /* Signal that this thread has finished and leave the mutex. */
1553 pthread_cond_signal(&cond_join);
1554 threads_mutex_join_unlock();
1560 /* threads_join_all_threads ****************************************************
1562 Join all non-daemon threads.
1564 *******************************************************************************/
1566 void threads_join_all_threads(void)
1570 /* get current thread */
1574 /* this thread is waiting for all non-daemon threads to exit */
1576 threads_thread_state_waiting(t);
1578 /* enter join mutex */
1580 threads_mutex_join_lock();
1582 /* Wait for condition as long as we have non-daemon threads. We
1583 compare against 1 because the current (main thread) is also a
1584 non-daemon thread. */
1586 while (threads_list_get_non_daemons() > 1)
1587 pthread_cond_wait(&cond_join, &mutex_join);
1589 /* leave join mutex */
1591 threads_mutex_join_unlock();
1595 /* threads_timespec_earlier ****************************************************
1597 Return true if timespec tv1 is earlier than timespec tv2.
1600 tv1..........first timespec
1601 tv2..........second timespec
1604 true, if the first timespec is earlier
1606 *******************************************************************************/
1608 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1609 const struct timespec *tv2)
1611 return (tv1->tv_sec < tv2->tv_sec)
1613 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1617 /* threads_current_time_is_earlier_than ****************************************
1619 Check if the current time is earlier than the given timespec.
1622 tv...........the timespec to compare against
1625 true, if the current time is earlier
1627 *******************************************************************************/
1629 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1631 struct timeval tvnow;
1632 struct timespec tsnow;
1634 /* get current time */
1636 if (gettimeofday(&tvnow, NULL) != 0)
1637 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1639 /* convert it to a timespec */
1641 tsnow.tv_sec = tvnow.tv_sec;
1642 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1644 /* compare current time with the given timespec */
1646 return threads_timespec_earlier(&tsnow, tv);
1650 /* threads_wait_with_timeout ***************************************************
1652 Wait until the given point in time on a monitor until either
1653 we are notified, we are interrupted, or the time is up.
1656 t............the current thread
1657 wakeupTime...absolute (latest) wakeup time
1658 If both tv_sec and tv_nsec are zero, this function
1659 waits for an unlimited amount of time.
1662 true.........if the wait has been interrupted,
1663 false........if the wait was ended by notification or timeout
1665 *******************************************************************************/
1667 static bool threads_wait_with_timeout(threadobject *thread,
1668 struct timespec *wakeupTime)
1670 bool wasinterrupted;
1672 /* acquire the waitmutex */
1674 pthread_mutex_lock(&thread->waitmutex);
1676 /* mark us as sleeping */
1678 thread->sleeping = true;
1680 /* wait on waitcond */
1682 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1684 while (!thread->interrupted && !thread->signaled
1685 && threads_current_time_is_earlier_than(wakeupTime))
1687 threads_thread_state_timed_waiting(thread);
1689 pthread_cond_timedwait(&thread->waitcond, &thread->waitmutex,
1692 threads_thread_state_runnable(thread);
1697 while (!thread->interrupted && !thread->signaled) {
1698 threads_thread_state_waiting(thread);
1700 pthread_cond_wait(&thread->waitcond, &thread->waitmutex);
1702 threads_thread_state_runnable(thread);
1706 /* check if we were interrupted */
1708 wasinterrupted = thread->interrupted;
1710 /* reset all flags */
1712 thread->interrupted = false;
1713 thread->signaled = false;
1714 thread->sleeping = false;
1716 /* release the waitmutex */
1718 pthread_mutex_unlock(&thread->waitmutex);
1720 return wasinterrupted;
1724 /* threads_wait_with_timeout_relative ******************************************
1726 Wait for the given maximum amount of time on a monitor until either
1727 we are notified, we are interrupted, or the time is up.
1730 t............the current thread
1731 millis.......milliseconds to wait
1732 nanos........nanoseconds to wait
1735 true.........if the wait has been interrupted,
1736 false........if the wait was ended by notification or timeout
1738 *******************************************************************************/
1740 bool threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1743 struct timespec wakeupTime;
1745 /* calculate the the (latest) wakeup time */
1747 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1751 return threads_wait_with_timeout(thread, &wakeupTime);
1755 /* threads_calc_absolute_time **************************************************
1757 Calculate the absolute point in time a given number of ms and ns from now.
1760 millis............milliseconds from now
1761 nanos.............nanoseconds from now
1764 *tm...............receives the timespec of the absolute point in time
1766 *******************************************************************************/
1768 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1770 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1773 gettimeofday(&tv, NULL);
1774 tv.tv_sec += millis / 1000;
1776 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1777 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1778 tm->tv_nsec = nsec % 1000000000;
1787 /* threads_thread_interrupt ****************************************************
1789 Interrupt the given thread.
1791 The thread gets the "waitcond" signal and
1792 its interrupted flag is set to true.
1795 thread............the thread to interrupt
1797 *******************************************************************************/
1799 void threads_thread_interrupt(threadobject *thread)
1801 /* Signal the thread a "waitcond" and tell it that it has been
1804 pthread_mutex_lock(&thread->waitmutex);
1806 /* Interrupt blocking system call using a signal. */
1808 pthread_kill(thread->tid, SIGHUP);
1810 if (thread->sleeping)
1811 pthread_cond_signal(&thread->waitcond);
1813 thread->interrupted = true;
1815 pthread_mutex_unlock(&thread->waitmutex);
1819 /* threads_check_if_interrupted_and_reset **************************************
1821 Check if the current thread has been interrupted and reset the
1825 true, if the current thread had been interrupted
1827 *******************************************************************************/
1829 bool threads_check_if_interrupted_and_reset(void)
1831 threadobject *thread;
1834 thread = THREADOBJECT;
1836 /* get interrupted flag */
1838 intr = thread->interrupted;
1840 /* reset interrupted flag */
1842 thread->interrupted = false;
1848 /* threads_thread_has_been_interrupted *****************************************
1850 Check if the given thread has been interrupted
1853 t............the thread to check
1856 true, if the given thread had been interrupted
1858 *******************************************************************************/
1860 bool threads_thread_has_been_interrupted(threadobject *thread)
1862 return thread->interrupted;
1866 /* threads_sleep ***************************************************************
1868 Sleep the current thread for the specified amount of time.
1870 *******************************************************************************/
1872 void threads_sleep(s8 millis, s4 nanos)
1874 threadobject *thread;
1875 struct timespec wakeupTime;
1876 bool wasinterrupted;
1878 thread = THREADOBJECT;
1880 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1882 wasinterrupted = threads_wait_with_timeout(thread, &wakeupTime);
1885 exceptions_throw_interruptedexception();
1889 /* threads_yield ***************************************************************
1891 Yield to the scheduler.
1893 *******************************************************************************/
1895 void threads_yield(void)
1902 * These are local overrides for various environment variables in Emacs.
1903 * Please do not remove this and leave it at the end of the file, where
1904 * Emacs will automagically detect them.
1905 * ---------------------------------------------------------------------
1908 * indent-tabs-mode: t
1912 * vim:noexpandtab:sw=4:ts=4: