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 7963 2007-05-24 10:21:16Z 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 /* 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 s4 threads_cast_sendsignals(s4 sig)
377 /* iterate over all started threads */
381 for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
382 /* don't send the signal to ourself */
387 /* don't send the signal to NEW threads (because they are not
388 completely initialized) */
390 if (t->state == THREAD_STATE_NEW)
393 /* send the signal */
395 pthread_kill(t->tid, sig);
397 /* increase threads count */
407 static void threads_cast_darwinstop(void)
409 threadobject *tobj = mainthreadobj;
410 threadobject *self = THREADOBJECT;
415 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
416 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
417 #if defined(__I386__)
418 i386_thread_state_t thread_state;
420 ppc_thread_state_t thread_state;
422 mach_port_t thread = tobj->mach_thread;
425 r = thread_suspend(thread);
427 if (r != KERN_SUCCESS)
428 vm_abort("thread_suspend failed");
430 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
431 &thread_state_count);
433 if (r != KERN_SUCCESS)
434 vm_abort("thread_get_state failed");
436 md_critical_section_restart((ucontext_t *) &thread_state);
438 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
441 if (r != KERN_SUCCESS)
442 vm_abort("thread_set_state failed");
446 } while (tobj != mainthreadobj);
449 static void threads_cast_darwinresume(void)
451 threadobject *tobj = mainthreadobj;
452 threadobject *self = THREADOBJECT;
457 mach_port_t thread = tobj->mach_thread;
460 r = thread_resume(thread);
462 if (r != KERN_SUCCESS)
463 vm_abort("thread_resume failed");
467 } while (tobj != mainthreadobj);
472 #if defined(__MIPS__)
473 static void threads_cast_irixresume(void)
475 pthread_mutex_lock(&suspend_ack_lock);
476 pthread_cond_broadcast(&suspend_cond);
477 pthread_mutex_unlock(&suspend_ack_lock);
481 #if !defined(DISABLE_GC)
483 void threads_cast_stopworld(void)
485 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
489 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
491 /* lock the threads lists */
495 #if defined(__DARWIN__)
496 threads_cast_darwinstop();
497 #elif defined(__CYGWIN__)
501 /* send all threads the suspend signal */
503 count = threads_cast_sendsignals(GC_signum1());
505 /* wait for all threads signaled to suspend */
507 for (i = 0; i < count; i++)
508 threads_sem_wait(&suspend_ack);
511 /* ATTENTION: Don't unlock the threads-lists here so that
512 non-signaled NEW threads can't change their state and execute
517 void threads_cast_startworld(void)
519 #if defined(__DARWIN__)
520 threads_cast_darwinresume();
521 #elif defined(__MIPS__)
522 threads_cast_irixresume();
523 #elif defined(__CYGWIN__)
527 (void) threads_cast_sendsignals(GC_signum2());
530 /* unlock the threads lists */
532 threads_list_unlock();
538 #if !defined(__DARWIN__)
539 static void threads_sigsuspend_handler(ucontext_t *_uc)
544 /* XXX TWISTI: this is just a quick hack */
545 #if defined(ENABLE_JIT)
546 md_critical_section_restart(_uc);
549 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
550 (not POSIX async-safe). */
551 #if defined(__IRIX__)
552 pthread_mutex_lock(&suspend_ack_lock);
553 threads_sem_post(&suspend_ack);
554 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
555 pthread_mutex_unlock(&suspend_ack_lock);
556 #elif defined(__CYGWIN__)
560 threads_sem_post(&suspend_ack);
564 sigdelset(&sigs, sig);
569 /* This function is called from Boehm GC code. */
571 int cacao_suspendhandler(ucontext_t *_uc)
573 if (stopworldwhere != STOPWORLD_FROM_CLASS_NUMBERING)
576 threads_sigsuspend_handler(_uc);
581 #endif /* DISABLE_GC */
584 /* threads_set_current_threadobject ********************************************
586 Set the current thread object.
589 thread.......the thread object to set
591 *******************************************************************************/
593 void threads_set_current_threadobject(threadobject *thread)
595 #if !defined(HAVE___THREAD)
596 if (pthread_setspecific(threads_current_threadobject_key, thread) != 0)
597 vm_abort("threads_set_current_threadobject: pthread_setspecific failed: %s", strerror(errno));
599 threads_current_threadobject = thread;
604 /* threads_impl_thread_new *****************************************************
606 Initialize implementation fields of a threadobject.
609 t....the threadobject
611 *******************************************************************************/
613 void threads_impl_thread_new(threadobject *t)
615 /* get the pthread id */
617 t->tid = pthread_self();
619 /* initialize the mutex and the condition */
621 pthread_mutex_init(&(t->waitmutex), NULL);
622 pthread_cond_init(&(t->waitcond), NULL);
626 /* threads_impl_thread_free ****************************************************
628 Cleanup thread stuff.
631 t....the threadobject
633 *******************************************************************************/
635 void threads_impl_thread_free(threadobject *t)
637 /* destroy the mutex and the condition */
639 if (pthread_mutex_destroy(&(t->waitmutex)) != 0)
640 vm_abort("threads_impl_thread_free: pthread_mutex_destroy failed: %s",
643 if (pthread_cond_destroy(&(t->waitcond)) != 0)
644 vm_abort("threads_impl_thread_free: pthread_cond_destroy failed: %s",
649 /* threads_get_current_threadobject ********************************************
651 Return the threadobject of the current thread.
654 the current threadobject * (an instance of java.lang.Thread)
656 *******************************************************************************/
658 threadobject *threads_get_current_threadobject(void)
664 /* threads_impl_preinit ********************************************************
666 Do some early initialization of stuff required.
668 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
669 is called AFTER this function!
671 *******************************************************************************/
673 void threads_impl_preinit(void)
675 pthread_mutex_init(&stopworldlock, NULL);
677 /* initialize exit mutex and condition (on exit we join all
680 pthread_mutex_init(&mutex_join, NULL);
681 pthread_cond_init(&cond_join, NULL);
683 #if !defined(HAVE___THREAD)
684 pthread_key_create(&threads_current_threadobject_key, NULL);
687 threads_sem_init(&suspend_ack, 0, 0);
691 /* threads_table_lock **********************************************************
693 Initialize threads table mutex.
695 *******************************************************************************/
697 void threads_impl_table_init(void)
699 pthread_mutex_init(&mutex_threads_list, NULL);
703 /* threads_list_lock ***********************************************************
705 Enter the threads table mutex.
707 NOTE: We need this function as we can't use an internal lock for
708 the threads lists because the thread's lock is initialized in
709 threads_table_add (when we have the thread index), but we
710 already need the lock at the entry of the function.
712 *******************************************************************************/
714 void threads_list_lock(void)
716 if (pthread_mutex_lock(&mutex_threads_list) != 0)
717 vm_abort("threads_table_lock: pthread_mutex_lock failed: %s",
722 /* threads_list_unlock *********************************************************
724 Leave the threads list mutex.
726 *******************************************************************************/
728 void threads_list_unlock(void)
730 if (pthread_mutex_unlock(&mutex_threads_list) != 0)
731 vm_abort("threads_table_unlock: pthread_mutex_unlock failed: %s",
736 /* threads_init ****************************************************************
738 Initializes the threads required by the JVM: main, finalizer.
740 *******************************************************************************/
742 bool threads_init(void)
744 threadobject *mainthread;
745 java_objectheader *threadname;
747 java_objectheader *o;
749 #if defined(ENABLE_JAVASE)
750 java_lang_ThreadGroup *threadgroup;
754 #if defined(WITH_CLASSPATH_GNU)
755 java_lang_VMThread *vmt;
760 /* get methods we need in this file */
762 #if defined(WITH_CLASSPATH_GNU)
764 class_resolveclassmethod(class_java_lang_Thread,
766 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
767 class_java_lang_Thread,
771 class_resolveclassmethod(class_java_lang_Thread,
773 utf_new_char("(Ljava/lang/String;)V"),
774 class_java_lang_Thread,
778 if (method_thread_init == NULL)
781 /* Get the main-thread (NOTE: The main threads is always the first
782 thread in the list). */
784 mainthread = threads_list_first();
786 /* create a java.lang.Thread for the main thread */
788 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
793 /* set the object in the internal data structure */
795 mainthread->object = t;
797 #if defined(ENABLE_INTRP)
798 /* create interpreter stack */
801 MSET(intrp_main_stack, 0, u1, opt_stacksize);
802 mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
806 threadname = javastring_new(utf_new_char("main"));
808 #if defined(ENABLE_JAVASE)
809 /* allocate and init ThreadGroup */
811 threadgroup = (java_lang_ThreadGroup *)
812 native_new_and_init(class_java_lang_ThreadGroup);
814 if (threadgroup == NULL)
818 #if defined(WITH_CLASSPATH_GNU)
819 /* create a java.lang.VMThread for the main thread */
821 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
829 vmt->vmdata = (java_lang_Object *) mainthread;
831 /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
832 o = (java_objectheader *) t;
834 (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
836 #elif defined(WITH_CLASSPATH_CLDC1_1)
839 t->vm_thread = (java_lang_Object *) mainthread;
841 /* call public Thread(String name) */
843 o = (java_objectheader *) t;
845 (void) vm_call_method(method_thread_init, o, threadname);
851 #if defined(ENABLE_JAVASE)
852 t->group = threadgroup;
854 /* add main thread to java.lang.ThreadGroup */
856 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
858 utf_java_lang_Thread__V,
859 class_java_lang_ThreadGroup,
862 o = (java_objectheader *) threadgroup;
864 (void) vm_call_method(m, o, t);
870 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
872 /* initialize the thread attribute object */
874 if (pthread_attr_init(&attr) != 0)
875 vm_abort("threads_init: pthread_attr_init failed: %s", strerror(errno));
877 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
878 vm_abort("threads_init: pthread_attr_setdetachstate failed: %s",
882 if (opt_verbosethreads) {
883 printf("[Starting thread ");
884 threads_thread_print_info(mainthread);
889 /* everything's ok */
895 /* threads_startup_thread ******************************************************
897 Thread startup function called by pthread_create.
899 Thread which have a startup.function != NULL are marked as internal
900 threads. All other threads are threated as normal Java threads.
902 NOTE: This function is not called directly by pthread_create. The Boehm GC
903 inserts its own GC_start_routine in between, which then calls
907 arg..........the argument passed to pthread_create, ie. a pointer to
908 a startupinfo struct. CAUTION: When the `psem` semaphore
909 is posted, the startupinfo struct becomes invalid! (It
910 is allocated on the stack of threads_start_thread.)
912 ******************************************************************************/
914 static void *threads_startup_thread(void *arg)
916 startupinfo *startup;
917 threadobject *thread;
918 #if defined(WITH_CLASSPATH_GNU)
919 java_lang_VMThread *vmt;
924 java_objectheader *o;
925 functionptr function;
927 #if defined(ENABLE_INTRP)
928 u1 *intrp_thread_stack;
930 /* create interpreter stack */
933 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
934 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
937 intrp_thread_stack = NULL;
940 /* get passed startupinfo structure and the values in there */
944 thread = startup->thread;
945 function = startup->function;
946 psem = startup->psem;
948 /* Seems like we've encountered a situation where thread->tid was
949 not set by pthread_create. We alleviate this problem by waiting
950 for pthread_create to return. */
952 threads_sem_wait(startup->psem_first);
954 #if defined(__DARWIN__)
955 thread->mach_thread = mach_thread_self();
958 /* store the internal thread data-structure in the TSD */
960 threads_set_current_threadobject(thread);
962 /* set our priority */
964 threads_set_thread_priority(thread->tid, thread->object->priority);
966 /* thread is completely initialized */
968 threads_thread_state_runnable(thread);
970 /* tell threads_startup_thread that we registered ourselves */
971 /* CAUTION: *startup becomes invalid with this! */
974 threads_sem_post(psem);
976 #if defined(ENABLE_INTRP)
977 /* set interpreter stack */
980 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
983 #if defined(ENABLE_JVMTI)
984 /* fire thread start event */
987 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
991 if (opt_verbosethreads) {
992 printf("[Starting thread ");
993 threads_thread_print_info(thread);
998 /* find and run the Thread.run()V method if no other function was passed */
1000 if (function == NULL) {
1001 #if defined(WITH_CLASSPATH_GNU)
1002 /* We need to start the run method of
1003 java.lang.VMThread. Since this is a final class, we can use
1004 the class object directly. */
1006 c = class_java_lang_VMThread;
1007 #elif defined(WITH_CLASSPATH_CLDC1_1)
1008 c = thread->object->header.vftbl->class;
1011 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1014 vm_abort("threads_startup_thread: run() method not found in class");
1016 /* set ThreadMXBean variables */
1018 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1019 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1021 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1022 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1023 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1024 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1026 #if defined(WITH_CLASSPATH_GNU)
1027 /* we need to start the run method of java.lang.VMThread */
1029 vmt = (java_lang_VMThread *) thread->object->vmThread;
1030 o = (java_objectheader *) vmt;
1032 #elif defined(WITH_CLASSPATH_CLDC1_1)
1033 o = (java_objectheader *) thread->object;
1036 /* run the thread */
1038 (void) vm_call_method(m, o);
1041 /* set ThreadMXBean variables */
1043 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1044 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1046 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1047 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1048 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1049 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1051 /* call passed function, e.g. finalizer_thread */
1056 #if !defined(NDEBUG)
1057 if (opt_verbosethreads) {
1058 printf("[Stopping thread ");
1059 threads_thread_print_info(thread);
1064 #if defined(ENABLE_JVMTI)
1065 /* fire thread end event */
1068 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1071 if (!threads_detach_thread(thread))
1072 vm_abort("threads_startup_thread: threads_detach_thread failed");
1074 /* set ThreadMXBean variables */
1076 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1082 /* threads_impl_thread_start ***************************************************
1084 Start a thread in the JVM. Both (vm internal and java) thread
1088 thread....the thread object
1089 f.........function to run in the new thread. NULL means that the
1090 "run" method of the object `t` should be called
1092 ******************************************************************************/
1094 void threads_impl_thread_start(threadobject *thread, functionptr f)
1098 pthread_attr_t attr;
1099 startupinfo startup;
1102 /* fill startupinfo structure passed by pthread_create to
1103 * threads_startup_thread */
1105 startup.thread = thread;
1106 startup.function = f; /* maybe we don't call Thread.run()V */
1107 startup.psem = &sem;
1108 startup.psem_first = &sem_first;
1110 threads_sem_init(&sem, 0, 0);
1111 threads_sem_init(&sem_first, 0, 0);
1113 /* initialize thread attributes */
1115 if (pthread_attr_init(&attr) != 0)
1116 vm_abort("threads_impl_thread_start: pthread_attr_init failed: %s",
1119 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
1120 vm_abort("threads_impl_thread_start: pthread_attr_setdetachstate failed: %s",
1123 /* initialize thread stacksize */
1125 if (pthread_attr_setstacksize(&attr, opt_stacksize))
1126 vm_abort("threads_impl_thread_start: pthread_attr_setstacksize failed: %s",
1129 /* create the thread */
1131 ret = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1133 /* destroy the thread attributes */
1135 if (pthread_attr_destroy(&attr) != 0)
1136 vm_abort("threads_impl_thread_start: pthread_attr_destroy failed: %s",
1139 /* check for pthread_create error */
1142 vm_abort("threads_impl_thread_start: pthread_create failed: %s",
1145 /* signal that pthread_create has returned, so thread->tid is valid */
1147 threads_sem_post(&sem_first);
1149 /* wait here until the thread has entered itself into the thread list */
1151 threads_sem_wait(&sem);
1156 sem_destroy(&sem_first);
1160 /* threads_set_thread_priority *************************************************
1162 Set the priority of the given thread.
1165 tid..........thread id
1166 priority.....priority to set
1168 ******************************************************************************/
1170 void threads_set_thread_priority(pthread_t tid, int priority)
1172 struct sched_param schedp;
1175 pthread_getschedparam(tid, &policy, &schedp);
1176 schedp.sched_priority = priority;
1177 pthread_setschedparam(tid, policy, &schedp);
1181 /* threads_attach_current_thread ***********************************************
1183 Attaches the current thread to the VM. Used in JNI.
1185 *******************************************************************************/
1187 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
1189 threadobject *thread;
1191 java_objectheader *s;
1192 java_objectheader *o;
1193 java_lang_Thread *t;
1195 #if defined(ENABLE_JAVASE)
1196 java_lang_ThreadGroup *group;
1197 threadobject *mainthread;
1201 #if defined(WITH_CLASSPATH_GNU)
1202 java_lang_VMThread *vmt;
1205 /* create internal thread data-structure */
1207 thread = threads_thread_new();
1209 /* create a java.lang.Thread object */
1211 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
1218 /* thread is a Java thread and running */
1220 thread->flags = THREAD_FLAG_JAVA;
1223 thread->flags |= THREAD_FLAG_DAEMON;
1225 /* thread is completely initialized */
1227 threads_thread_state_runnable(thread);
1229 #if !defined(NDEBUG)
1230 if (opt_verbosethreads) {
1231 printf("[Attaching thread ");
1232 threads_thread_print_info(thread);
1237 #if defined(ENABLE_INTRP)
1238 /* create interpreter stack */
1241 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1242 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
1246 #if defined(WITH_CLASSPATH_GNU)
1247 /* create a java.lang.VMThread object */
1249 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
1254 /* set the thread */
1257 vmt->vmdata = (java_lang_Object *) thread;
1258 #elif defined(WITH_CLASSPATH_CLDC1_1)
1259 t->vm_thread = (java_lang_Object *) thread;
1262 if (vm_aargs != NULL) {
1263 u = utf_new_char(vm_aargs->name);
1264 #if defined(ENABLE_JAVASE)
1265 group = (java_lang_ThreadGroup *) vm_aargs->group;
1270 #if defined(ENABLE_JAVASE)
1271 /* get the main thread */
1273 mainthread = threads_list_first();
1274 group = mainthread->object->group;
1278 /* the the thread name */
1280 s = javastring_new(u);
1282 /* for convenience */
1284 o = (java_objectheader *) thread->object;
1286 #if defined(WITH_CLASSPATH_GNU)
1287 (void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
1289 #elif defined(WITH_CLASSPATH_CLDC1_1)
1290 (void) vm_call_method(method_thread_init, o, s);
1296 #if defined(ENABLE_JAVASE)
1297 /* store the thread group in the object */
1299 thread->object->group = group;
1301 /* add thread to given thread-group */
1303 m = class_resolveclassmethod(group->header.vftbl->class,
1305 utf_java_lang_Thread__V,
1306 class_java_lang_ThreadGroup,
1309 o = (java_objectheader *) group;
1311 (void) vm_call_method(m, o, t);
1321 /* threads_detach_thread *******************************************************
1323 Detaches the passed thread from the VM. Used in JNI.
1325 *******************************************************************************/
1327 bool threads_detach_thread(threadobject *thread)
1329 #if defined(ENABLE_JAVASE)
1330 java_lang_ThreadGroup *group;
1332 java_objectheader *o;
1333 java_lang_Thread *t;
1336 /* XXX implement uncaught exception stuff (like JamVM does) */
1338 #if defined(ENABLE_JAVASE)
1339 /* remove thread from the thread group */
1341 group = thread->object->group;
1343 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1345 if (group != NULL) {
1346 m = class_resolveclassmethod(group->header.vftbl->class,
1348 utf_java_lang_Thread__V,
1349 class_java_lang_ThreadGroup,
1355 o = (java_objectheader *) group;
1358 (void) vm_call_method(m, o, t);
1365 /* thread is terminated */
1367 threads_thread_state_terminated(thread);
1369 #if !defined(NDEBUG)
1370 if (opt_verbosethreads) {
1371 printf("[Detaching thread ");
1372 threads_thread_print_info(thread);
1377 /* signal that this thread has finished */
1379 pthread_mutex_lock(&mutex_join);
1380 pthread_cond_signal(&cond_join);
1381 pthread_mutex_unlock(&mutex_join);
1383 /* free the vm internal thread object */
1385 threads_thread_free(thread);
1391 /* threads_join_all_threads ****************************************************
1393 Join all non-daemon threads.
1395 *******************************************************************************/
1397 void threads_join_all_threads(void)
1401 /* get current thread */
1405 /* this thread is waiting for all non-daemon threads to exit */
1407 threads_thread_state_waiting(t);
1409 /* enter join mutex */
1411 pthread_mutex_lock(&mutex_join);
1413 /* Wait for condition as long as we have non-daemon threads. We
1414 compare against 1 because the current (main thread) is also a
1415 non-daemon thread. */
1417 while (threads_list_get_non_daemons() > 1)
1418 pthread_cond_wait(&cond_join, &mutex_join);
1420 /* leave join mutex */
1422 pthread_mutex_unlock(&mutex_join);
1426 /* threads_timespec_earlier ****************************************************
1428 Return true if timespec tv1 is earlier than timespec tv2.
1431 tv1..........first timespec
1432 tv2..........second timespec
1435 true, if the first timespec is earlier
1437 *******************************************************************************/
1439 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1440 const struct timespec *tv2)
1442 return (tv1->tv_sec < tv2->tv_sec)
1444 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1448 /* threads_current_time_is_earlier_than ****************************************
1450 Check if the current time is earlier than the given timespec.
1453 tv...........the timespec to compare against
1456 true, if the current time is earlier
1458 *******************************************************************************/
1460 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1462 struct timeval tvnow;
1463 struct timespec tsnow;
1465 /* get current time */
1467 if (gettimeofday(&tvnow, NULL) != 0)
1468 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1470 /* convert it to a timespec */
1472 tsnow.tv_sec = tvnow.tv_sec;
1473 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1475 /* compare current time with the given timespec */
1477 return threads_timespec_earlier(&tsnow, tv);
1481 /* threads_wait_with_timeout ***************************************************
1483 Wait until the given point in time on a monitor until either
1484 we are notified, we are interrupted, or the time is up.
1487 t............the current thread
1488 wakeupTime...absolute (latest) wakeup time
1489 If both tv_sec and tv_nsec are zero, this function
1490 waits for an unlimited amount of time.
1493 true.........if the wait has been interrupted,
1494 false........if the wait was ended by notification or timeout
1496 *******************************************************************************/
1498 static bool threads_wait_with_timeout(threadobject *thread,
1499 struct timespec *wakeupTime)
1501 bool wasinterrupted;
1503 /* acquire the waitmutex */
1505 pthread_mutex_lock(&thread->waitmutex);
1507 /* mark us as sleeping */
1509 thread->sleeping = true;
1511 /* wait on waitcond */
1513 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1515 while (!thread->interrupted && !thread->signaled
1516 && threads_current_time_is_earlier_than(wakeupTime))
1518 threads_thread_state_timed_waiting(thread);
1520 pthread_cond_timedwait(&thread->waitcond, &thread->waitmutex,
1523 threads_thread_state_runnable(thread);
1528 while (!thread->interrupted && !thread->signaled) {
1529 threads_thread_state_waiting(thread);
1531 pthread_cond_wait(&thread->waitcond, &thread->waitmutex);
1533 threads_thread_state_runnable(thread);
1537 /* check if we were interrupted */
1539 wasinterrupted = thread->interrupted;
1541 /* reset all flags */
1543 thread->interrupted = false;
1544 thread->signaled = false;
1545 thread->sleeping = false;
1547 /* release the waitmutex */
1549 pthread_mutex_unlock(&thread->waitmutex);
1551 return wasinterrupted;
1555 /* threads_wait_with_timeout_relative ******************************************
1557 Wait for the given maximum amount of time on a monitor until either
1558 we are notified, we are interrupted, or the time is up.
1561 t............the current thread
1562 millis.......milliseconds to wait
1563 nanos........nanoseconds to wait
1566 true.........if the wait has been interrupted,
1567 false........if the wait was ended by notification or timeout
1569 *******************************************************************************/
1571 bool threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1574 struct timespec wakeupTime;
1576 /* calculate the the (latest) wakeup time */
1578 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1582 return threads_wait_with_timeout(thread, &wakeupTime);
1586 /* threads_calc_absolute_time **************************************************
1588 Calculate the absolute point in time a given number of ms and ns from now.
1591 millis............milliseconds from now
1592 nanos.............nanoseconds from now
1595 *tm...............receives the timespec of the absolute point in time
1597 *******************************************************************************/
1599 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1601 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1604 gettimeofday(&tv, NULL);
1605 tv.tv_sec += millis / 1000;
1607 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1608 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1609 tm->tv_nsec = nsec % 1000000000;
1618 /* threads_thread_interrupt ****************************************************
1620 Interrupt the given thread.
1622 The thread gets the "waitcond" signal and
1623 its interrupted flag is set to true.
1626 thread............the thread to interrupt
1628 *******************************************************************************/
1630 void threads_thread_interrupt(threadobject *thread)
1632 /* Signal the thread a "waitcond" and tell it that it has been
1635 pthread_mutex_lock(&thread->waitmutex);
1637 /* Interrupt blocking system call using a signal. */
1639 pthread_kill(thread->tid, SIGHUP);
1641 if (thread->sleeping)
1642 pthread_cond_signal(&thread->waitcond);
1644 thread->interrupted = true;
1646 pthread_mutex_unlock(&thread->waitmutex);
1650 /* threads_check_if_interrupted_and_reset **************************************
1652 Check if the current thread has been interrupted and reset the
1656 true, if the current thread had been interrupted
1658 *******************************************************************************/
1660 bool threads_check_if_interrupted_and_reset(void)
1662 threadobject *thread;
1665 thread = THREADOBJECT;
1667 /* get interrupted flag */
1669 intr = thread->interrupted;
1671 /* reset interrupted flag */
1673 thread->interrupted = false;
1679 /* threads_thread_has_been_interrupted *****************************************
1681 Check if the given thread has been interrupted
1684 t............the thread to check
1687 true, if the given thread had been interrupted
1689 *******************************************************************************/
1691 bool threads_thread_has_been_interrupted(threadobject *thread)
1693 return thread->interrupted;
1697 /* threads_sleep ***************************************************************
1699 Sleep the current thread for the specified amount of time.
1701 *******************************************************************************/
1703 void threads_sleep(s8 millis, s4 nanos)
1705 threadobject *thread;
1706 struct timespec wakeupTime;
1707 bool wasinterrupted;
1709 thread = THREADOBJECT;
1711 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1713 wasinterrupted = threads_wait_with_timeout(thread, &wakeupTime);
1716 exceptions_throw_interruptedexception();
1720 /* threads_yield ***************************************************************
1722 Yield to the scheduler.
1724 *******************************************************************************/
1726 void threads_yield(void)
1733 * These are local overrides for various environment variables in Emacs.
1734 * Please do not remove this and leave it at the end of the file, where
1735 * Emacs will automagically detect them.
1736 * ---------------------------------------------------------------------
1739 * indent-tabs-mode: t
1743 * vim:noexpandtab:sw=4:ts=4: