1 /* src/threads/native/threads.c - native threads support
3 Copyright (C) 1996-2005, 2006 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 Contact: cacao@cacaojvm.org
29 Changes: Christian Thalinger
32 $Id: threads.c 5900 2006-11-04 17:30:44Z michi $
39 /* XXX cleanup these includes */
44 #include <sys/types.h>
57 #if !defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
58 # include "machine-instr.h"
60 # include "threads/native/generic-primitives.h"
63 #include "mm/gc-common.h"
64 #include "mm/memory.h"
65 #include "native/native.h"
66 #include "native/include/java_lang_Object.h"
67 #include "native/include/java_lang_Throwable.h"
68 #include "native/include/java_lang_Thread.h"
69 #include "native/include/java_lang_ThreadGroup.h"
70 #include "native/include/java_lang_VMThread.h"
71 #include "threads/native/threads.h"
72 #include "toolbox/avl.h"
73 #include "toolbox/logging.h"
74 #include "vm/builtin.h"
75 #include "vm/exceptions.h"
76 #include "vm/global.h"
77 #include "vm/loader.h"
78 #include "vm/options.h"
79 #include "vm/stringlocal.h"
81 #include "vm/jit/asmpart.h"
83 #if !defined(__DARWIN__)
84 # if defined(__LINUX__)
85 # define GC_LINUX_THREADS
86 # elif defined(__MIPS__)
87 # define GC_IRIX_THREADS
89 # include <semaphore.h>
90 # if defined(ENABLE_GC_BOEHM)
91 # include "mm/boehm-gc/include/gc.h"
95 #if defined(ENABLE_JVMTI)
96 #include "native/jvmti/cacaodbg.h"
99 #if defined(__DARWIN__)
100 /* Darwin has no working semaphore implementation. This one is taken
104 This is a very simple semaphore implementation for darwin. It
105 is implemented in terms of pthreads calls so it isn't async signal
106 safe. This isn't a problem because signals aren't used to
107 suspend threads on darwin.
110 static int sem_init(sem_t *sem, int pshared, int value)
117 if (pthread_mutex_init(&sem->mutex, NULL) < 0)
120 if (pthread_cond_init(&sem->cond, NULL) < 0)
126 static int sem_post(sem_t *sem)
128 if (pthread_mutex_lock(&sem->mutex) < 0)
133 if (pthread_cond_signal(&sem->cond) < 0) {
134 pthread_mutex_unlock(&sem->mutex);
138 if (pthread_mutex_unlock(&sem->mutex) < 0)
144 static int sem_wait(sem_t *sem)
146 if (pthread_mutex_lock(&sem->mutex) < 0)
149 while (sem->value == 0) {
150 pthread_cond_wait(&sem->cond, &sem->mutex);
155 if (pthread_mutex_unlock(&sem->mutex) < 0)
161 static int sem_destroy(sem_t *sem)
163 if (pthread_cond_destroy(&sem->cond) < 0)
166 if (pthread_mutex_destroy(&sem->mutex) < 0)
171 #endif /* defined(__DARWIN__) */
174 /* internally used constants **************************************************/
176 /* CAUTION: Do not change these values. Boehm GC code depends on them. */
177 #define STOPWORLD_FROM_GC 1
178 #define STOPWORLD_FROM_CLASS_NUMBERING 2
180 #define THREADS_INITIAL_TABLE_SIZE 8
183 /* startupinfo *****************************************************************
185 Struct used to pass info from threads_start_thread to
186 threads_startup_thread.
188 ******************************************************************************/
191 threadobject *thread; /* threadobject for this thread */
192 functionptr function; /* function to run in the new thread */
193 sem_t *psem; /* signals when thread has been entered */
194 /* in the thread list */
195 sem_t *psem_first; /* signals when pthread_create has returned */
199 /* prototypes *****************************************************************/
201 static void threads_table_init(void);
202 static s4 threads_table_add(threadobject *thread);
203 static void threads_table_remove(threadobject *thread);
204 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
206 #if !defined(NDEBUG) && 0
207 static void threads_table_dump(FILE *file);
210 /******************************************************************************/
211 /* GLOBAL VARIABLES */
212 /******************************************************************************/
214 /* the main thread */
215 threadobject *mainthreadobj;
217 static methodinfo *method_thread_init;
218 static methodinfo *method_threadgroup_add;
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 threads table */
230 static threads_table_t threads_table;
232 /* global compiler mutex */
233 static pthread_mutex_t compiler_mutex;
235 /* global mutex for changing the thread list */
236 static pthread_mutex_t threadlistlock;
238 /* global mutex for stop-the-world */
239 static pthread_mutex_t stopworldlock;
241 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
243 static volatile int stopworldwhere;
245 /* semaphore used for acknowleding thread suspension */
246 static sem_t suspend_ack;
247 #if defined(__MIPS__)
248 static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
249 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
252 static pthread_attr_t threadattr;
254 /* mutexes used by the fake atomic instructions */
255 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
256 pthread_mutex_t _atomic_add_lock = PTHREAD_MUTEX_INITIALIZER;
257 pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
258 pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
262 /* threads_sem_init ************************************************************
264 Initialize a semaphore. Checks against errors and interruptions.
267 sem..............the semaphore to initialize
268 shared...........true if this semaphore will be shared between processes
269 value............the initial value for the semaphore
271 *******************************************************************************/
273 void threads_sem_init(sem_t *sem, bool shared, int value)
280 r = sem_init(sem, shared, value);
283 } while (errno == EINTR);
285 vm_abort("sem_init failed: %s", strerror(errno));
289 /* threads_sem_wait ************************************************************
291 Wait for a semaphore, non-interruptible.
293 IMPORTANT: Always use this function instead of `sem_wait` directly, as
294 `sem_wait` may be interrupted by signals!
297 sem..............the semaphore to wait on
299 *******************************************************************************/
301 void threads_sem_wait(sem_t *sem)
311 } while (errno == EINTR);
313 vm_abort("sem_wait failed: %s", strerror(errno));
317 /* threads_sem_post ************************************************************
319 Increase the count of a semaphore. Checks for errors.
322 sem..............the semaphore to increase the count of
324 *******************************************************************************/
326 void threads_sem_post(sem_t *sem)
332 /* unlike sem_wait, sem_post is not interruptible */
338 vm_abort("sem_post failed: %s", strerror(errno));
342 /* threads_set_thread_priority *************************************************
344 Set the priority of the given thread.
347 tid..........thread id
348 priority.....priority to set
350 ******************************************************************************/
352 static void threads_set_thread_priority(pthread_t tid, int priority)
354 struct sched_param schedp;
357 pthread_getschedparam(tid, &policy, &schedp);
358 schedp.sched_priority = priority;
359 pthread_setschedparam(tid, policy, &schedp);
363 /* compiler_lock ***************************************************************
365 Enter the compiler lock.
367 ******************************************************************************/
369 void compiler_lock(void)
371 pthread_mutex_lock(&compiler_mutex);
375 /* compiler_unlock *************************************************************
377 Release the compiler lock.
379 ******************************************************************************/
381 void compiler_unlock(void)
383 pthread_mutex_unlock(&compiler_mutex);
387 /* lock_stopworld **************************************************************
389 Enter the stopworld lock, specifying why the world shall be stopped.
392 where........ STOPWORLD_FROM_GC (1) from within GC
393 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
395 ******************************************************************************/
397 void lock_stopworld(int where)
399 pthread_mutex_lock(&stopworldlock);
400 stopworldwhere = where;
404 /* unlock_stopworld ************************************************************
406 Release the stopworld lock.
408 ******************************************************************************/
410 void unlock_stopworld(void)
413 pthread_mutex_unlock(&stopworldlock);
416 #if !defined(__DARWIN__)
417 /* Caller must hold threadlistlock */
418 static int threads_cast_sendsignals(int sig, int count)
421 threadobject *tobj = mainthreadobj;
422 threadobject *self = THREADOBJECT;
428 } while (tobj != mainthreadobj);
431 assert(tobj == mainthreadobj);
435 pthread_kill(tobj->tid, sig);
437 } while (tobj != mainthreadobj);
444 static void threads_cast_darwinstop(void)
446 threadobject *tobj = mainthreadobj;
447 threadobject *self = THREADOBJECT;
452 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
453 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
454 #if defined(__I386__)
455 i386_thread_state_t thread_state;
457 ppc_thread_state_t thread_state;
459 mach_port_t thread = tobj->mach_thread;
462 r = thread_suspend(thread);
464 if (r != KERN_SUCCESS)
465 vm_abort("thread_suspend failed");
467 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
468 &thread_state_count);
470 if (r != KERN_SUCCESS)
471 vm_abort("thread_get_state failed");
473 thread_restartcriticalsection((ucontext_t *) &thread_state);
475 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
478 if (r != KERN_SUCCESS)
479 vm_abort("thread_set_state failed");
483 } while (tobj != mainthreadobj);
486 static void threads_cast_darwinresume(void)
488 threadobject *tobj = mainthreadobj;
489 threadobject *self = THREADOBJECT;
494 mach_port_t thread = tobj->mach_thread;
497 r = thread_resume(thread);
499 if (r != KERN_SUCCESS)
500 vm_abort("thread_resume failed");
504 } while (tobj != mainthreadobj);
509 #if defined(__MIPS__)
510 static void threads_cast_irixresume(void)
512 pthread_mutex_lock(&suspend_ack_lock);
513 pthread_cond_broadcast(&suspend_cond);
514 pthread_mutex_unlock(&suspend_ack_lock);
518 void threads_cast_stopworld(void)
520 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
524 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
525 pthread_mutex_lock(&threadlistlock);
527 #if defined(__DARWIN__)
528 threads_cast_darwinstop();
529 #elif defined(__CYGWIN__)
533 count = threads_cast_sendsignals(GC_signum1(), 0);
534 for (i = 0; i < count; i++)
535 threads_sem_wait(&suspend_ack);
538 pthread_mutex_unlock(&threadlistlock);
541 void threads_cast_startworld(void)
543 pthread_mutex_lock(&threadlistlock);
544 #if defined(__DARWIN__)
545 threads_cast_darwinresume();
546 #elif defined(__MIPS__)
547 threads_cast_irixresume();
548 #elif defined(__CYGWIN__)
552 threads_cast_sendsignals(GC_signum2(), -1);
554 pthread_mutex_unlock(&threadlistlock);
558 #if !defined(__DARWIN__)
559 static void threads_sigsuspend_handler(ucontext_t *ctx)
564 /* XXX TWISTI: this is just a quick hack */
565 #if defined(ENABLE_JIT)
566 thread_restartcriticalsection(ctx);
569 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
570 (not POSIX async-safe). */
571 #if defined(__IRIX__)
572 pthread_mutex_lock(&suspend_ack_lock);
573 threads_sem_post(&suspend_ack);
574 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
575 pthread_mutex_unlock(&suspend_ack_lock);
576 #elif defined(__CYGWIN__)
580 threads_sem_post(&suspend_ack);
584 sigdelset(&sigs, sig);
589 /* This function is called from Boehm GC code. */
591 int cacao_suspendhandler(ucontext_t *ctx)
593 if (stopworldwhere != STOPWORLD_FROM_CLASS_NUMBERING)
596 threads_sigsuspend_handler(ctx);
602 /* threads_set_current_threadobject ********************************************
604 Set the current thread object.
607 thread.......the thread object to set
609 *******************************************************************************/
611 static void threads_set_current_threadobject(threadobject *thread)
613 #if !defined(HAVE___THREAD)
614 pthread_setspecific(threads_current_threadobject_key, thread);
616 threads_current_threadobject = thread;
621 /* threads_get_current_threadobject ********************************************
623 Return the threadobject of the current thread.
626 the current threadobject * (an instance of java.lang.VMThread)
628 *******************************************************************************/
630 threadobject *threads_get_current_threadobject(void)
636 /* threads_preinit *************************************************************
638 Do some early initialization of stuff required.
640 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
641 is called AFTER this function!
643 *******************************************************************************/
645 void threads_preinit(void)
647 pthread_mutexattr_t mutexattr;
648 pthread_mutexattr_init(&mutexattr);
649 pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
650 pthread_mutex_init(&compiler_mutex, &mutexattr);
651 pthread_mutexattr_destroy(&mutexattr);
653 pthread_mutex_init(&threadlistlock, NULL);
654 pthread_mutex_init(&stopworldlock, NULL);
656 mainthreadobj = NEW(threadobject);
657 mainthreadobj->tid = pthread_self();
658 mainthreadobj->index = 1;
659 mainthreadobj->thinlock = lock_pre_compute_thinlock(mainthreadobj->index);
661 #if !defined(HAVE___THREAD)
662 pthread_key_create(&threads_current_threadobject_key, NULL);
664 threads_set_current_threadobject(mainthreadobj);
666 threads_sem_init(&suspend_ack, 0, 0);
668 /* initialize the threads table */
670 threads_table_init();
672 /* initialize subsystems */
680 /* threads_init ****************************************************************
682 Initializes the threads required by the JVM: main, finalizer.
684 *******************************************************************************/
686 bool threads_init(void)
688 java_lang_String *threadname;
689 java_lang_Thread *mainthread;
690 java_lang_ThreadGroup *threadgroup;
691 threadobject *tempthread;
693 tempthread = mainthreadobj;
695 /* XXX We have to find a new way to free lock records */
696 /* with the new locking algorithm. */
697 /* lock_record_free_pools(mainthreadobj->ee.lockrecordpools); */
699 /* This is kinda tricky, we grow the java.lang.Thread object so we
700 can keep the execution environment there. No Thread object must
701 have been created at an earlier time. */
703 class_java_lang_VMThread->instancesize = sizeof(threadobject);
705 /* get methods we need in this file */
708 class_resolveclassmethod(class_java_lang_Thread,
710 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
711 class_java_lang_Thread,
714 if (method_thread_init == NULL)
717 method_threadgroup_add =
718 class_resolveclassmethod(class_java_lang_ThreadGroup,
719 utf_new_char("addThread"),
720 utf_new_char("(Ljava/lang/Thread;)V"),
721 class_java_lang_ThreadGroup,
724 if (method_threadgroup_add == NULL)
727 /* create a VMThread */
729 mainthreadobj = (threadobject *) builtin_new(class_java_lang_VMThread);
731 if (mainthreadobj == NULL)
734 FREE(tempthread, threadobject);
736 threads_init_threadobject(&mainthreadobj->o);
738 threads_set_current_threadobject(mainthreadobj);
740 lock_init_execution_env(mainthreadobj);
742 mainthreadobj->next = mainthreadobj;
743 mainthreadobj->prev = mainthreadobj;
745 threads_table_add(mainthreadobj);
747 /* mark main thread as Java thread */
749 mainthreadobj->flags = THREAD_FLAG_JAVA;
751 #if defined(ENABLE_INTRP)
752 /* create interpreter stack */
755 MSET(intrp_main_stack, 0, u1, opt_stacksize);
756 mainthreadobj->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
760 threadname = javastring_new(utf_new_char("main"));
762 /* allocate and init ThreadGroup */
764 threadgroup = (java_lang_ThreadGroup *)
765 native_new_and_init(class_java_lang_ThreadGroup);
768 throw_exception_exit();
770 /* create a Thread */
772 mainthread = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
774 if (mainthread == NULL)
775 throw_exception_exit();
777 mainthreadobj->o.thread = mainthread;
779 /* call Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
781 (void) vm_call_method(method_thread_init, (java_objectheader *) mainthread,
782 mainthreadobj, threadname, NORM_PRIORITY, false);
787 mainthread->group = threadgroup;
789 /* add mainthread to ThreadGroup */
791 (void) vm_call_method(method_threadgroup_add,
792 (java_objectheader *) threadgroup,
798 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
800 /* initialize the thread attribute object */
802 if (pthread_attr_init(&threadattr)) {
803 log_println("pthread_attr_init failed: %s", strerror(errno));
807 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
809 /* everything's ok */
815 /* threads_table_init *********************************************************
817 Initialize the global threads table.
819 ******************************************************************************/
821 static void threads_table_init(void)
826 size = THREADS_INITIAL_TABLE_SIZE;
828 threads_table.size = size;
829 threads_table.table = MNEW(threads_table_entry_t, size);
831 /* link the entries in a freelist */
833 for (i=0; i<size; ++i) {
834 threads_table.table[i].nextfree = i+1;
837 /* terminate the freelist */
839 threads_table.table[size-1].nextfree = 0; /* index 0 is never free */
843 /* threads_table_add **********************************************************
845 Add a thread to the global threads table. The index is entered in the
846 threadobject. The thinlock value for the thread is pre-computed.
849 thread............the thread to add
852 The table index for the newly added thread. This value has also been
853 entered in the threadobject.
856 The caller must hold the threadlistlock!
858 ******************************************************************************/
860 static s4 threads_table_add(threadobject *thread)
867 /* table[0] serves as the head of the freelist */
869 index = threads_table.table[0].nextfree;
871 /* if we got a free index, use it */
875 threads_table.table[0].nextfree = threads_table.table[index].nextfree;
876 threads_table.table[index].thread = thread;
877 thread->index = index;
878 thread->thinlock = lock_pre_compute_thinlock(index);
882 /* we must grow the table */
884 oldsize = threads_table.size;
885 newsize = oldsize * 2;
887 threads_table.table = MREALLOC(threads_table.table, threads_table_entry_t,
889 threads_table.size = newsize;
891 /* link the new entries to a free list */
893 for (i=oldsize; i<newsize; ++i) {
894 threads_table.table[i].nextfree = i+1;
897 /* terminate the freelist */
899 threads_table.table[newsize-1].nextfree = 0; /* index 0 is never free */
901 /* use the first of the new entries */
908 /* threads_table_remove *******************************************************
910 Remove a thread from the global threads table.
913 thread............the thread to remove
916 The caller must hold the threadlistlock!
918 ******************************************************************************/
920 static void threads_table_remove(threadobject *thread)
924 index = thread->index;
926 /* put the index into the freelist */
928 threads_table.table[index] = threads_table.table[0];
929 threads_table.table[0].nextfree = index;
931 /* delete the index in the threadobject to discover bugs */
937 /* threads_init_threadobject **************************************************
939 Initialize implementation fields of a java.lang.VMThread.
942 t............the java.lang.VMThread
944 ******************************************************************************/
946 void threads_init_threadobject(java_lang_VMThread *t)
948 threadobject *thread = (threadobject*) t;
950 thread->tid = pthread_self();
954 /* TODO destroy all those things */
955 pthread_mutex_init(&(thread->joinmutex), NULL);
956 pthread_cond_init(&(thread->joincond), NULL);
958 pthread_mutex_init(&(thread->waitmutex), NULL);
959 pthread_cond_init(&(thread->waitcond), NULL);
961 thread->interrupted = false;
962 thread->signaled = false;
963 thread->sleeping = false;
967 /* threads_startup_thread ******************************************************
969 Thread startup function called by pthread_create.
971 Thread which have a startup.function != NULL are marked as internal
972 threads. All other threads are threated as normal Java threads.
974 NOTE: This function is not called directly by pthread_create. The Boehm GC
975 inserts its own GC_start_routine in between, which then calls
979 t............the argument passed to pthread_create, ie. a pointer to
980 a startupinfo struct. CAUTION: When the `psem` semaphore
981 is posted, the startupinfo struct becomes invalid! (It
982 is allocated on the stack of threads_start_thread.)
984 ******************************************************************************/
986 static void *threads_startup_thread(void *t)
988 startupinfo *startup;
989 threadobject *thread;
993 functionptr function;
995 #if defined(ENABLE_INTRP)
996 u1 *intrp_thread_stack;
998 /* create interpreter stack */
1001 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
1002 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
1005 intrp_thread_stack = NULL;
1008 /* get passed startupinfo structure and the values in there */
1011 t = NULL; /* make sure it's not used wrongly */
1013 thread = startup->thread;
1014 function = startup->function;
1015 psem = startup->psem;
1017 /* Seems like we've encountered a situation where thread->tid was not set by
1018 * pthread_create. We alleviate this problem by waiting for pthread_create
1020 threads_sem_wait(startup->psem_first);
1022 /* set the thread object */
1024 #if defined(__DARWIN__)
1025 thread->mach_thread = mach_thread_self();
1027 threads_set_current_threadobject(thread);
1029 /* insert the thread into the threadlist and the threads table */
1031 pthread_mutex_lock(&threadlistlock);
1033 thread->prev = mainthreadobj;
1034 thread->next = tnext = mainthreadobj->next;
1035 mainthreadobj->next = thread;
1036 tnext->prev = thread;
1038 threads_table_add(thread);
1040 pthread_mutex_unlock(&threadlistlock);
1042 /* init data structures of this thread */
1044 lock_init_execution_env(thread);
1046 /* tell threads_startup_thread that we registered ourselves */
1047 /* CAUTION: *startup becomes invalid with this! */
1050 threads_sem_post(psem);
1052 /* set our priority */
1054 threads_set_thread_priority(thread->tid, thread->o.thread->priority);
1056 #if defined(ENABLE_INTRP)
1057 /* set interpreter stack */
1060 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1063 #if defined(ENABLE_JVMTI)
1064 /* fire thread start event */
1067 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1070 /* find and run the Thread.run()V method if no other function was passed */
1072 if (function == NULL) {
1073 /* this is a normal Java thread */
1075 thread->flags |= THREAD_FLAG_JAVA;
1077 method = class_resolveclassmethod(thread->o.header.vftbl->class,
1080 thread->o.header.vftbl->class,
1086 /* increase total started thread count */
1088 _Jv_jvm->total_started_thread_count++;
1090 (void) vm_call_method(method, (java_objectheader *) thread);
1093 /* this is an internal thread */
1095 thread->flags |= THREAD_FLAG_INTERNAL;
1097 /* increase total started thread count */
1099 _Jv_jvm->total_started_thread_count++;
1101 /* call passed function, e.g. finalizer_thread */
1106 #if defined(ENABLE_JVMTI)
1107 /* fire thread end event */
1110 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1113 threads_detach_thread(thread);
1119 /* threads_start_thread ********************************************************
1121 Start a thread in the JVM.
1124 t............the java.lang.Thread object
1125 function.....function to run in the new thread. NULL means that the
1126 "run" method of the object `t` should be called
1128 ******************************************************************************/
1130 void threads_start_thread(java_lang_Thread *t, functionptr function)
1134 pthread_attr_t attr;
1135 startupinfo startup;
1136 threadobject *thread;
1138 thread = (threadobject *) t->vmThread;
1140 /* fill startupinfo structure passed by pthread_create to
1141 * threads_startup_thread */
1143 startup.thread = thread;
1144 startup.function = function; /* maybe we don't call Thread.run()V */
1145 startup.psem = &sem;
1146 startup.psem_first = &sem_first;
1148 threads_sem_init(&sem, 0, 0);
1149 threads_sem_init(&sem_first, 0, 0);
1151 /* initialize thread attribute object */
1153 if (pthread_attr_init(&attr))
1154 vm_abort("pthread_attr_init failed: %s", strerror(errno));
1156 /* initialize thread stacksize */
1158 if (pthread_attr_setstacksize(&attr, opt_stacksize))
1159 vm_abort("pthread_attr_setstacksize failed: %s", strerror(errno));
1161 /* create the thread */
1163 if (pthread_create(&thread->tid, &attr, threads_startup_thread, &startup))
1164 vm_abort("pthread_create failed: %s", strerror(errno));
1166 /* signal that pthread_create has returned, so thread->tid is valid */
1168 threads_sem_post(&sem_first);
1170 /* wait here until the thread has entered itself into the thread list */
1172 threads_sem_wait(&sem);
1177 sem_destroy(&sem_first);
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;
1190 java_lang_Thread *t;
1192 java_lang_String *s;
1193 java_lang_ThreadGroup *group;
1194 java_objectheader *o;
1196 /* create a java.lang.VMThread object */
1198 thread = (threadobject *) builtin_new(class_java_lang_VMThread);
1203 threads_init_threadobject(&thread->o);
1204 threads_set_current_threadobject(thread);
1205 lock_init_execution_env(thread);
1207 /* insert the thread into the threadlist and the threads table */
1209 pthread_mutex_lock(&threadlistlock);
1211 thread->prev = mainthreadobj;
1212 thread->next = mainthreadobj->next;
1213 mainthreadobj->next = thread;
1214 thread->next->prev = thread;
1216 threads_table_add(thread);
1218 pthread_mutex_unlock(&threadlistlock);
1220 /* mark main thread as Java thread */
1222 thread->flags = THREAD_FLAG_JAVA;
1224 #if defined(ENABLE_INTRP)
1225 /* create interpreter stack */
1228 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1229 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
1233 /* create a java.lang.Thread object */
1235 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
1240 thread->o.thread = t;
1242 if (vm_aargs != NULL) {
1243 u = utf_new_char(vm_aargs->name);
1244 group = (java_lang_ThreadGroup *) vm_aargs->group;
1248 group = mainthreadobj->o.thread->group;
1251 s = javastring_new(u);
1253 o = (java_objectheader *) t;
1255 (void) vm_call_method(method_thread_init, o, thread, s, NORM_PRIORITY,
1261 /* store the thread group in the object */
1265 o = (java_objectheader *) group;
1267 (void) vm_call_method(method_threadgroup_add, o, t);
1276 /* threads_detach_thread *******************************************************
1278 Detaches the passed thread from the VM. Used in JNI.
1280 *******************************************************************************/
1282 bool threads_detach_thread(threadobject *thread)
1284 java_lang_Thread *t;
1285 java_lang_ThreadGroup *group;
1287 java_objectheader *o;
1289 /* Allow lock record pools to be used by other threads. They
1290 cannot be deleted so we'd better not waste them. */
1292 /* XXX We have to find a new way to free lock records */
1293 /* with the new locking algorithm. */
1294 /* lock_record_free_pools(thread->ee.lockrecordpools); */
1296 /* XXX implement uncaught exception stuff (like JamVM does) */
1298 /* remove thread from the thread group */
1300 t = thread->o.thread;
1303 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1305 if (group != NULL) {
1306 m = class_resolveclassmethod(group->header.vftbl->class,
1308 utf_java_lang_Thread__V,
1309 class_java_lang_ThreadGroup,
1315 o = (java_objectheader *) group;
1317 (void) vm_call_method(m, o, t);
1323 /* remove thread from thread list and threads table, do this
1326 pthread_mutex_lock(&threadlistlock);
1328 thread->next->prev = thread->prev;
1329 thread->prev->next = thread->next;
1331 threads_table_remove(thread);
1333 pthread_mutex_unlock(&threadlistlock);
1335 /* reset thread id (lock on joinmutex? TWISTI) */
1337 pthread_mutex_lock(&thread->joinmutex);
1339 pthread_mutex_unlock(&thread->joinmutex);
1341 /* tell everyone that a thread has finished */
1343 pthread_cond_broadcast(&thread->joincond);
1349 /* threads_find_non_daemon_thread **********************************************
1351 Helper function used by threads_join_all_threads for finding
1352 non-daemon threads that are still running.
1354 *******************************************************************************/
1356 /* At the end of the program, we wait for all running non-daemon
1359 static threadobject *threads_find_non_daemon_thread(threadobject *thread)
1361 while (thread != mainthreadobj) {
1362 if (!thread->o.thread->daemon)
1364 thread = thread->prev;
1371 /* threads_join_all_threads ****************************************************
1373 Join all non-daemon threads.
1375 *******************************************************************************/
1377 void threads_join_all_threads(void)
1379 threadobject *thread;
1381 pthread_mutex_lock(&threadlistlock);
1383 while ((thread = threads_find_non_daemon_thread(mainthreadobj->prev)) != NULL) {
1385 pthread_mutex_lock(&thread->joinmutex);
1387 pthread_mutex_unlock(&threadlistlock);
1390 pthread_cond_wait(&thread->joincond, &thread->joinmutex);
1392 pthread_mutex_unlock(&thread->joinmutex);
1394 pthread_mutex_lock(&threadlistlock);
1397 pthread_mutex_unlock(&threadlistlock);
1401 /* threads_timespec_earlier ****************************************************
1403 Return true if timespec tv1 is earlier than timespec tv2.
1406 tv1..........first timespec
1407 tv2..........second timespec
1410 true, if the first timespec is earlier
1412 *******************************************************************************/
1414 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1415 const struct timespec *tv2)
1417 return (tv1->tv_sec < tv2->tv_sec)
1419 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1423 /* threads_current_time_is_earlier_than ****************************************
1425 Check if the current time is earlier than the given timespec.
1428 tv...........the timespec to compare against
1431 true, if the current time is earlier
1433 *******************************************************************************/
1435 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1437 struct timeval tvnow;
1438 struct timespec tsnow;
1440 /* get current time */
1442 if (gettimeofday(&tvnow, NULL) != 0)
1443 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1445 /* convert it to a timespec */
1447 tsnow.tv_sec = tvnow.tv_sec;
1448 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1450 /* compare current time with the given timespec */
1452 return threads_timespec_earlier(&tsnow, tv);
1456 /* threads_wait_with_timeout ***************************************************
1458 Wait until the given point in time on a monitor until either
1459 we are notified, we are interrupted, or the time is up.
1462 t............the current thread
1463 wakeupTime...absolute (latest) wakeup time
1464 If both tv_sec and tv_nsec are zero, this function
1465 waits for an unlimited amount of time.
1468 true.........if the wait has been interrupted,
1469 false........if the wait was ended by notification or timeout
1471 *******************************************************************************/
1473 static bool threads_wait_with_timeout(threadobject *t,
1474 struct timespec *wakeupTime)
1476 bool wasinterrupted;
1478 /* acquire the waitmutex */
1480 pthread_mutex_lock(&t->waitmutex);
1482 /* mark us as sleeping */
1486 /* wait on waitcond */
1488 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1490 while (!t->interrupted && !t->signaled
1491 && threads_current_time_is_earlier_than(wakeupTime))
1493 pthread_cond_timedwait(&t->waitcond, &t->waitmutex, wakeupTime);
1498 while (!t->interrupted && !t->signaled)
1499 pthread_cond_wait(&t->waitcond, &t->waitmutex);
1502 /* check if we were interrupted */
1504 wasinterrupted = t->interrupted;
1506 /* reset all flags */
1508 t->interrupted = false;
1509 t->signaled = false;
1510 t->sleeping = false;
1512 /* release the waitmutex */
1514 pthread_mutex_unlock(&t->waitmutex);
1516 return wasinterrupted;
1520 /* threads_wait_with_timeout_relative ******************************************
1522 Wait for the given maximum amount of time on a monitor until either
1523 we are notified, we are interrupted, or the time is up.
1526 t............the current thread
1527 millis.......milliseconds to wait
1528 nanos........nanoseconds to wait
1531 true.........if the wait has been interrupted,
1532 false........if the wait was ended by notification or timeout
1534 *******************************************************************************/
1536 bool threads_wait_with_timeout_relative(threadobject *t,
1540 struct timespec wakeupTime;
1542 /* calculate the the (latest) wakeup time */
1544 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1548 return threads_wait_with_timeout(t, &wakeupTime);
1552 /* threads_calc_absolute_time **************************************************
1554 Calculate the absolute point in time a given number of ms and ns from now.
1557 millis............milliseconds from now
1558 nanos.............nanoseconds from now
1561 *tm...............receives the timespec of the absolute point in time
1563 *******************************************************************************/
1565 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1567 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1570 gettimeofday(&tv, NULL);
1571 tv.tv_sec += millis / 1000;
1573 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1574 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1575 tm->tv_nsec = nsec % 1000000000;
1584 /* threads_thread_interrupt ****************************************************
1586 Interrupt the given thread.
1588 The thread gets the "waitcond" signal and
1589 its interrupted flag is set to true.
1592 thread............the thread to interrupt
1594 *******************************************************************************/
1596 void threads_thread_interrupt(java_lang_VMThread *thread)
1600 t = (threadobject *) thread;
1602 /* Signal the thread a "waitcond" and tell it that it has been
1605 pthread_mutex_lock(&t->waitmutex);
1607 /* Interrupt blocking system call using a signal. */
1609 pthread_kill(t->tid, SIGHUP);
1612 pthread_cond_signal(&t->waitcond);
1614 t->interrupted = true;
1616 pthread_mutex_unlock(&t->waitmutex);
1620 /* threads_check_if_interrupted_and_reset **************************************
1622 Check if the current thread has been interrupted and reset the
1626 true, if the current thread had been interrupted
1628 *******************************************************************************/
1630 bool threads_check_if_interrupted_and_reset(void)
1635 t = (threadobject*) THREADOBJECT;
1637 intr = t->interrupted;
1639 t->interrupted = false;
1645 /* threads_thread_has_been_interrupted *********************************************************
1647 Check if the given thread has been interrupted
1650 t............the thread to check
1653 true, if the given thread had been interrupted
1655 *******************************************************************************/
1657 bool threads_thread_has_been_interrupted(java_lang_VMThread *thread)
1661 t = (threadobject*) thread;
1663 return t->interrupted;
1667 /* threads_sleep ***************************************************************
1669 Sleep the current thread for the specified amount of time.
1671 *******************************************************************************/
1673 void threads_sleep(s8 millis, s4 nanos)
1676 struct timespec wakeupTime;
1677 bool wasinterrupted;
1679 t = (threadobject *) THREADOBJECT;
1681 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1683 wasinterrupted = threads_wait_with_timeout(t, &wakeupTime);
1686 *exceptionptr = new_exception(string_java_lang_InterruptedException);
1690 /* threads_yield ***************************************************************
1692 Yield to the scheduler.
1694 *******************************************************************************/
1696 void threads_yield(void)
1702 /* threads_java_lang_Thread_set_priority ***************************************
1704 Set the priority for the given java.lang.Thread.
1707 t............the java.lang.Thread
1708 priority.....the priority
1710 *******************************************************************************/
1712 void threads_java_lang_Thread_set_priority(java_lang_Thread *t, s4 priority)
1714 threadobject *thread;
1716 thread = (threadobject*) t->vmThread;
1718 threads_set_thread_priority(thread->tid, priority);
1722 /* threads_dump ****************************************************************
1724 Dumps info for all threads running in the JVM. This function is
1725 called when SIGQUIT (<ctrl>-\) is sent to CACAO.
1727 *******************************************************************************/
1729 void threads_dump(void)
1731 threadobject *thread;
1732 java_lang_VMThread *vmt;
1733 java_lang_Thread *t;
1736 thread = mainthreadobj;
1738 /* XXX we should stop the world here */
1740 printf("Full thread dump CACAO "VERSION":\n");
1742 /* iterate over all started threads */
1745 /* get thread objects */
1750 /* the thread may be currently in initalization, don't print it */
1753 /* get thread name */
1755 name = javastring_toutf(t->name, false);
1758 utf_display_printable_ascii(name);
1764 #if SIZEOF_VOID_P == 8
1765 printf("prio=%d tid=0x%016lx\n", t->priority, (long) thread->tid);
1767 printf("prio=%d tid=0x%08lx\n", t->priority, (long) thread->tid);
1770 /* dump trace of thread */
1772 stacktrace_dump_trace(thread);
1775 thread = thread->next;
1776 } while ((thread != NULL) && (thread != mainthreadobj));
1780 /* threads_table_dump *********************************************************
1782 Dump the threads table for debugging purposes.
1785 file..............stream to write to
1787 ******************************************************************************/
1789 #if !defined(NDEBUG) && 0
1790 static void threads_table_dump(FILE *file)
1796 pthread_mutex_lock(&threadlistlock);
1798 size = threads_table.size;
1800 fprintf(file, "======== THREADS TABLE (size %d) ========\n", size);
1802 for (i=0; i<size; ++i) {
1803 index = threads_table.table[i].nextfree;
1805 fprintf(file, "%4d: ", i);
1808 fprintf(file, "free, nextfree = %d\n", (int) index);
1811 fprintf(file, "thread %p\n", (void*) threads_table.table[i].thread);
1815 fprintf(file, "======== END OF THREADS TABLE ========\n");
1817 pthread_mutex_unlock(&threadlistlock);
1822 * These are local overrides for various environment variables in Emacs.
1823 * Please do not remove this and leave it at the end of the file, where
1824 * Emacs will automagically detect them.
1825 * ---------------------------------------------------------------------
1828 * indent-tabs-mode: t
1832 * vim:noexpandtab:sw=4:ts=4: