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 5884 2006-10-31 20:11:28Z twisti $
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"
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 # include "mm/boehm-gc/include/gc.h"
93 #if defined(ENABLE_JVMTI)
94 #include "native/jvmti/cacaodbg.h"
97 #if defined(__DARWIN__)
98 /* Darwin has no working semaphore implementation. This one is taken
102 This is a very simple semaphore implementation for darwin. It
103 is implemented in terms of pthreads calls so it isn't async signal
104 safe. This isn't a problem because signals aren't used to
105 suspend threads on darwin.
108 static int sem_init(sem_t *sem, int pshared, int value)
115 if (pthread_mutex_init(&sem->mutex, NULL) < 0)
118 if (pthread_cond_init(&sem->cond, NULL) < 0)
124 static int sem_post(sem_t *sem)
126 if (pthread_mutex_lock(&sem->mutex) < 0)
131 if (pthread_cond_signal(&sem->cond) < 0) {
132 pthread_mutex_unlock(&sem->mutex);
136 if (pthread_mutex_unlock(&sem->mutex) < 0)
142 static int sem_wait(sem_t *sem)
144 if (pthread_mutex_lock(&sem->mutex) < 0)
147 while (sem->value == 0) {
148 pthread_cond_wait(&sem->cond, &sem->mutex);
153 if (pthread_mutex_unlock(&sem->mutex) < 0)
159 static int sem_destroy(sem_t *sem)
161 if (pthread_cond_destroy(&sem->cond) < 0)
164 if (pthread_mutex_destroy(&sem->mutex) < 0)
169 #endif /* defined(__DARWIN__) */
172 /* internally used constants **************************************************/
174 /* CAUTION: Do not change these values. Boehm GC code depends on them. */
175 #define STOPWORLD_FROM_GC 1
176 #define STOPWORLD_FROM_CLASS_NUMBERING 2
178 #define THREADS_INITIAL_TABLE_SIZE 8
181 /* startupinfo *****************************************************************
183 Struct used to pass info from threads_start_thread to
184 threads_startup_thread.
186 ******************************************************************************/
189 threadobject *thread; /* threadobject for this thread */
190 functionptr function; /* function to run in the new thread */
191 sem_t *psem; /* signals when thread has been entered */
192 /* in the thread list */
193 sem_t *psem_first; /* signals when pthread_create has returned */
197 /* prototypes *****************************************************************/
199 static void threads_table_init(void);
200 static s4 threads_table_add(threadobject *thread);
201 static void threads_table_remove(threadobject *thread);
202 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
204 #if !defined(NDEBUG) && 0
205 static void threads_table_dump(FILE *file);
208 /******************************************************************************/
209 /* GLOBAL VARIABLES */
210 /******************************************************************************/
212 /* the main thread */
213 threadobject *mainthreadobj;
215 static methodinfo *method_thread_init;
216 static methodinfo *method_threadgroup_add;
218 /* the thread object of the current thread */
219 /* This is either a thread-local variable defined with __thread, or */
220 /* a thread-specific value stored with key threads_current_threadobject_key. */
221 #if defined(HAVE___THREAD)
222 __thread threadobject *threads_current_threadobject;
224 pthread_key_t threads_current_threadobject_key;
227 /* global threads table */
228 static threads_table_t threads_table;
230 /* global compiler mutex */
231 static pthread_mutex_t compiler_mutex;
233 /* global mutex for changing the thread list */
234 static pthread_mutex_t threadlistlock;
236 /* global mutex for stop-the-world */
237 static pthread_mutex_t stopworldlock;
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 static pthread_attr_t threadattr;
252 /* mutexes used by the fake atomic instructions */
253 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
254 pthread_mutex_t _atomic_add_lock = PTHREAD_MUTEX_INITIALIZER;
255 pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
256 pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
260 /* threads_sem_init ************************************************************
262 Initialize a semaphore. Checks against errors and interruptions.
265 sem..............the semaphore to initialize
266 shared...........true if this semaphore will be shared between processes
267 value............the initial value for the semaphore
269 *******************************************************************************/
271 void threads_sem_init(sem_t *sem, bool shared, int value)
278 r = sem_init(sem, shared, value);
281 } while (errno == EINTR);
283 vm_abort("sem_init failed: %s", strerror(errno));
287 /* threads_sem_wait ************************************************************
289 Wait for a semaphore, non-interruptible.
291 IMPORTANT: Always use this function instead of `sem_wait` directly, as
292 `sem_wait` may be interrupted by signals!
295 sem..............the semaphore to wait on
297 *******************************************************************************/
299 void threads_sem_wait(sem_t *sem)
309 } while (errno == EINTR);
311 vm_abort("sem_wait failed: %s", strerror(errno));
315 /* threads_sem_post ************************************************************
317 Increase the count of a semaphore. Checks for errors.
320 sem..............the semaphore to increase the count of
322 *******************************************************************************/
324 void threads_sem_post(sem_t *sem)
330 /* unlike sem_wait, sem_post is not interruptible */
336 vm_abort("sem_post failed: %s", strerror(errno));
340 /* threads_set_thread_priority *************************************************
342 Set the priority of the given thread.
345 tid..........thread id
346 priority.....priority to set
348 ******************************************************************************/
350 static void threads_set_thread_priority(pthread_t tid, int priority)
352 struct sched_param schedp;
355 pthread_getschedparam(tid, &policy, &schedp);
356 schedp.sched_priority = priority;
357 pthread_setschedparam(tid, policy, &schedp);
361 /* compiler_lock ***************************************************************
363 Enter the compiler lock.
365 ******************************************************************************/
367 void compiler_lock(void)
369 pthread_mutex_lock(&compiler_mutex);
373 /* compiler_unlock *************************************************************
375 Release the compiler lock.
377 ******************************************************************************/
379 void compiler_unlock(void)
381 pthread_mutex_unlock(&compiler_mutex);
385 /* lock_stopworld **************************************************************
387 Enter the stopworld lock, specifying why the world shall be stopped.
390 where........ STOPWORLD_FROM_GC (1) from within GC
391 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
393 ******************************************************************************/
395 void lock_stopworld(int where)
397 pthread_mutex_lock(&stopworldlock);
398 stopworldwhere = where;
402 /* unlock_stopworld ************************************************************
404 Release the stopworld lock.
406 ******************************************************************************/
408 void unlock_stopworld(void)
411 pthread_mutex_unlock(&stopworldlock);
414 #if !defined(__DARWIN__)
415 /* Caller must hold threadlistlock */
416 static int threads_cast_sendsignals(int sig, int count)
419 threadobject *tobj = mainthreadobj;
420 threadobject *self = THREADOBJECT;
426 } while (tobj != mainthreadobj);
429 assert(tobj == mainthreadobj);
433 pthread_kill(tobj->tid, sig);
435 } while (tobj != mainthreadobj);
442 static void threads_cast_darwinstop(void)
444 threadobject *tobj = mainthreadobj;
445 threadobject *self = THREADOBJECT;
450 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
451 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
452 #if defined(__I386__)
453 i386_thread_state_t thread_state;
455 ppc_thread_state_t thread_state;
457 mach_port_t thread = tobj->mach_thread;
460 r = thread_suspend(thread);
462 if (r != KERN_SUCCESS)
463 vm_abort("thread_suspend failed");
465 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
466 &thread_state_count);
468 if (r != KERN_SUCCESS)
469 vm_abort("thread_get_state failed");
471 thread_restartcriticalsection((ucontext_t *) &thread_state);
473 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
476 if (r != KERN_SUCCESS)
477 vm_abort("thread_set_state failed");
481 } while (tobj != mainthreadobj);
484 static void threads_cast_darwinresume(void)
486 threadobject *tobj = mainthreadobj;
487 threadobject *self = THREADOBJECT;
492 mach_port_t thread = tobj->mach_thread;
495 r = thread_resume(thread);
497 if (r != KERN_SUCCESS)
498 vm_abort("thread_resume failed");
502 } while (tobj != mainthreadobj);
507 #if defined(__MIPS__)
508 static void threads_cast_irixresume(void)
510 pthread_mutex_lock(&suspend_ack_lock);
511 pthread_cond_broadcast(&suspend_cond);
512 pthread_mutex_unlock(&suspend_ack_lock);
516 void threads_cast_stopworld(void)
518 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
522 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
523 pthread_mutex_lock(&threadlistlock);
525 #if defined(__DARWIN__)
526 threads_cast_darwinstop();
527 #elif defined(__CYGWIN__)
531 count = threads_cast_sendsignals(GC_signum1(), 0);
532 for (i = 0; i < count; i++)
533 threads_sem_wait(&suspend_ack);
536 pthread_mutex_unlock(&threadlistlock);
539 void threads_cast_startworld(void)
541 pthread_mutex_lock(&threadlistlock);
542 #if defined(__DARWIN__)
543 threads_cast_darwinresume();
544 #elif defined(__MIPS__)
545 threads_cast_irixresume();
546 #elif defined(__CYGWIN__)
550 threads_cast_sendsignals(GC_signum2(), -1);
552 pthread_mutex_unlock(&threadlistlock);
556 #if !defined(__DARWIN__)
557 static void threads_sigsuspend_handler(ucontext_t *ctx)
562 /* XXX TWISTI: this is just a quick hack */
563 #if defined(ENABLE_JIT)
564 thread_restartcriticalsection(ctx);
567 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
568 (not POSIX async-safe). */
569 #if defined(__IRIX__)
570 pthread_mutex_lock(&suspend_ack_lock);
571 threads_sem_post(&suspend_ack);
572 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
573 pthread_mutex_unlock(&suspend_ack_lock);
574 #elif defined(__CYGWIN__)
578 threads_sem_post(&suspend_ack);
582 sigdelset(&sigs, sig);
587 /* This function is called from Boehm GC code. */
589 int cacao_suspendhandler(ucontext_t *ctx)
591 if (stopworldwhere != STOPWORLD_FROM_CLASS_NUMBERING)
594 threads_sigsuspend_handler(ctx);
600 /* threads_set_current_threadobject ********************************************
602 Set the current thread object.
605 thread.......the thread object to set
607 *******************************************************************************/
609 static void threads_set_current_threadobject(threadobject *thread)
611 #if !defined(HAVE___THREAD)
612 pthread_setspecific(threads_current_threadobject_key, thread);
614 threads_current_threadobject = thread;
619 /* threads_get_current_threadobject ********************************************
621 Return the threadobject of the current thread.
624 the current threadobject * (an instance of java.lang.VMThread)
626 *******************************************************************************/
628 threadobject *threads_get_current_threadobject(void)
634 /* threads_preinit *************************************************************
636 Do some early initialization of stuff required.
638 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
639 is called AFTER this function!
641 *******************************************************************************/
643 void threads_preinit(void)
645 pthread_mutexattr_t mutexattr;
646 pthread_mutexattr_init(&mutexattr);
647 pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
648 pthread_mutex_init(&compiler_mutex, &mutexattr);
649 pthread_mutexattr_destroy(&mutexattr);
651 pthread_mutex_init(&threadlistlock, NULL);
652 pthread_mutex_init(&stopworldlock, NULL);
654 mainthreadobj = NEW(threadobject);
655 mainthreadobj->tid = pthread_self();
656 mainthreadobj->index = 1;
657 mainthreadobj->thinlock = lock_pre_compute_thinlock(mainthreadobj->index);
659 #if !defined(HAVE___THREAD)
660 pthread_key_create(&threads_current_threadobject_key, NULL);
662 threads_set_current_threadobject(mainthreadobj);
664 threads_sem_init(&suspend_ack, 0, 0);
666 /* initialize the threads table */
668 threads_table_init();
670 /* initialize subsystems */
678 /* threads_init ****************************************************************
680 Initializes the threads required by the JVM: main, finalizer.
682 *******************************************************************************/
684 bool threads_init(void)
686 java_lang_String *threadname;
687 java_lang_Thread *mainthread;
688 java_lang_ThreadGroup *threadgroup;
689 threadobject *tempthread;
691 tempthread = mainthreadobj;
693 /* XXX We have to find a new way to free lock records */
694 /* with the new locking algorithm. */
695 /* lock_record_free_pools(mainthreadobj->ee.lockrecordpools); */
697 /* This is kinda tricky, we grow the java.lang.Thread object so we
698 can keep the execution environment there. No Thread object must
699 have been created at an earlier time. */
701 class_java_lang_VMThread->instancesize = sizeof(threadobject);
703 /* get methods we need in this file */
706 class_resolveclassmethod(class_java_lang_Thread,
708 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
709 class_java_lang_Thread,
712 if (method_thread_init == NULL)
715 method_threadgroup_add =
716 class_resolveclassmethod(class_java_lang_ThreadGroup,
717 utf_new_char("addThread"),
718 utf_new_char("(Ljava/lang/Thread;)V"),
719 class_java_lang_ThreadGroup,
722 if (method_threadgroup_add == NULL)
725 /* create a VMThread */
727 mainthreadobj = (threadobject *) builtin_new(class_java_lang_VMThread);
729 if (mainthreadobj == NULL)
732 FREE(tempthread, threadobject);
734 threads_init_threadobject(&mainthreadobj->o);
736 threads_set_current_threadobject(mainthreadobj);
738 lock_init_execution_env(mainthreadobj);
740 mainthreadobj->next = mainthreadobj;
741 mainthreadobj->prev = mainthreadobj;
743 threads_table_add(mainthreadobj);
745 /* mark main thread as Java thread */
747 mainthreadobj->flags = THREAD_FLAG_JAVA;
749 #if defined(ENABLE_INTRP)
750 /* create interpreter stack */
753 MSET(intrp_main_stack, 0, u1, opt_stacksize);
754 mainthreadobj->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
758 threadname = javastring_new(utf_new_char("main"));
760 /* allocate and init ThreadGroup */
762 threadgroup = (java_lang_ThreadGroup *)
763 native_new_and_init(class_java_lang_ThreadGroup);
766 throw_exception_exit();
768 /* create a Thread */
770 mainthread = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
772 if (mainthread == NULL)
773 throw_exception_exit();
775 mainthreadobj->o.thread = mainthread;
777 /* call Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
779 (void) vm_call_method(method_thread_init, (java_objectheader *) mainthread,
780 mainthreadobj, threadname, NORM_PRIORITY, false);
785 mainthread->group = threadgroup;
787 /* add mainthread to ThreadGroup */
789 (void) vm_call_method(method_threadgroup_add,
790 (java_objectheader *) threadgroup,
796 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
798 /* initialize the thread attribute object */
800 if (pthread_attr_init(&threadattr)) {
801 log_println("pthread_attr_init failed: %s", strerror(errno));
805 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
807 /* everything's ok */
813 /* threads_table_init *********************************************************
815 Initialize the global threads table.
817 ******************************************************************************/
819 static void threads_table_init(void)
824 size = THREADS_INITIAL_TABLE_SIZE;
826 threads_table.size = size;
827 threads_table.table = MNEW(threads_table_entry_t, size);
829 /* link the entries in a freelist */
831 for (i=0; i<size; ++i) {
832 threads_table.table[i].nextfree = i+1;
835 /* terminate the freelist */
837 threads_table.table[size-1].nextfree = 0; /* index 0 is never free */
841 /* threads_table_add **********************************************************
843 Add a thread to the global threads table. The index is entered in the
844 threadobject. The thinlock value for the thread is pre-computed.
847 thread............the thread to add
850 The table index for the newly added thread. This value has also been
851 entered in the threadobject.
854 The caller must hold the threadlistlock!
856 ******************************************************************************/
858 static s4 threads_table_add(threadobject *thread)
865 /* table[0] serves as the head of the freelist */
867 index = threads_table.table[0].nextfree;
869 /* if we got a free index, use it */
873 threads_table.table[0].nextfree = threads_table.table[index].nextfree;
874 threads_table.table[index].thread = thread;
875 thread->index = index;
876 thread->thinlock = lock_pre_compute_thinlock(index);
880 /* we must grow the table */
882 oldsize = threads_table.size;
883 newsize = oldsize * 2;
885 threads_table.table = MREALLOC(threads_table.table, threads_table_entry_t,
887 threads_table.size = newsize;
889 /* link the new entries to a free list */
891 for (i=oldsize; i<newsize; ++i) {
892 threads_table.table[i].nextfree = i+1;
895 /* terminate the freelist */
897 threads_table.table[newsize-1].nextfree = 0; /* index 0 is never free */
899 /* use the first of the new entries */
906 /* threads_table_remove *******************************************************
908 Remove a thread from the global threads table.
911 thread............the thread to remove
914 The caller must hold the threadlistlock!
916 ******************************************************************************/
918 static void threads_table_remove(threadobject *thread)
922 index = thread->index;
924 /* put the index into the freelist */
926 threads_table.table[index] = threads_table.table[0];
927 threads_table.table[0].nextfree = index;
929 /* delete the index in the threadobject to discover bugs */
935 /* threads_init_threadobject **************************************************
937 Initialize implementation fields of a java.lang.VMThread.
940 t............the java.lang.VMThread
942 ******************************************************************************/
944 void threads_init_threadobject(java_lang_VMThread *t)
946 threadobject *thread = (threadobject*) t;
948 thread->tid = pthread_self();
952 /* TODO destroy all those things */
953 pthread_mutex_init(&(thread->joinmutex), NULL);
954 pthread_cond_init(&(thread->joincond), NULL);
956 pthread_mutex_init(&(thread->waitmutex), NULL);
957 pthread_cond_init(&(thread->waitcond), NULL);
959 thread->interrupted = false;
960 thread->signaled = false;
961 thread->sleeping = false;
965 /* threads_startup_thread ******************************************************
967 Thread startup function called by pthread_create.
969 Thread which have a startup.function != NULL are marked as internal
970 threads. All other threads are threated as normal Java threads.
972 NOTE: This function is not called directly by pthread_create. The Boehm GC
973 inserts its own GC_start_routine in between, which then calls
977 t............the argument passed to pthread_create, ie. a pointer to
978 a startupinfo struct. CAUTION: When the `psem` semaphore
979 is posted, the startupinfo struct becomes invalid! (It
980 is allocated on the stack of threads_start_thread.)
982 ******************************************************************************/
984 static void *threads_startup_thread(void *t)
986 startupinfo *startup;
987 threadobject *thread;
991 functionptr function;
993 #if defined(ENABLE_INTRP)
994 u1 *intrp_thread_stack;
996 /* create interpreter stack */
999 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
1000 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
1003 intrp_thread_stack = NULL;
1006 /* get passed startupinfo structure and the values in there */
1009 t = NULL; /* make sure it's not used wrongly */
1011 thread = startup->thread;
1012 function = startup->function;
1013 psem = startup->psem;
1015 /* Seems like we've encountered a situation where thread->tid was not set by
1016 * pthread_create. We alleviate this problem by waiting for pthread_create
1018 threads_sem_wait(startup->psem_first);
1020 /* set the thread object */
1022 #if defined(__DARWIN__)
1023 thread->mach_thread = mach_thread_self();
1025 threads_set_current_threadobject(thread);
1027 /* insert the thread into the threadlist and the threads table */
1029 pthread_mutex_lock(&threadlistlock);
1031 thread->prev = mainthreadobj;
1032 thread->next = tnext = mainthreadobj->next;
1033 mainthreadobj->next = thread;
1034 tnext->prev = thread;
1036 threads_table_add(thread);
1038 pthread_mutex_unlock(&threadlistlock);
1040 /* init data structures of this thread */
1042 lock_init_execution_env(thread);
1044 /* tell threads_startup_thread that we registered ourselves */
1045 /* CAUTION: *startup becomes invalid with this! */
1048 threads_sem_post(psem);
1050 /* set our priority */
1052 threads_set_thread_priority(thread->tid, thread->o.thread->priority);
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 /* find and run the Thread.run()V method if no other function was passed */
1070 if (function == NULL) {
1071 /* this is a normal Java thread */
1073 thread->flags |= THREAD_FLAG_JAVA;
1075 method = class_resolveclassmethod(thread->o.header.vftbl->class,
1078 thread->o.header.vftbl->class,
1084 /* increase total started thread count */
1086 _Jv_jvm->total_started_thread_count++;
1088 (void) vm_call_method(method, (java_objectheader *) thread);
1091 /* this is an internal thread */
1093 thread->flags |= THREAD_FLAG_INTERNAL;
1095 /* increase total started thread count */
1097 _Jv_jvm->total_started_thread_count++;
1099 /* call passed function, e.g. finalizer_thread */
1104 #if defined(ENABLE_JVMTI)
1105 /* fire thread end event */
1108 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1111 threads_detach_thread(thread);
1117 /* threads_start_thread ********************************************************
1119 Start a thread in the JVM.
1122 t............the java.lang.Thread object
1123 function.....function to run in the new thread. NULL means that the
1124 "run" method of the object `t` should be called
1126 ******************************************************************************/
1128 void threads_start_thread(java_lang_Thread *t, functionptr function)
1132 pthread_attr_t attr;
1133 startupinfo startup;
1134 threadobject *thread;
1136 thread = (threadobject *) t->vmThread;
1138 /* fill startupinfo structure passed by pthread_create to
1139 * threads_startup_thread */
1141 startup.thread = thread;
1142 startup.function = function; /* maybe we don't call Thread.run()V */
1143 startup.psem = &sem;
1144 startup.psem_first = &sem_first;
1146 threads_sem_init(&sem, 0, 0);
1147 threads_sem_init(&sem_first, 0, 0);
1149 /* initialize thread attribute object */
1151 if (pthread_attr_init(&attr))
1152 vm_abort("pthread_attr_init failed: %s", strerror(errno));
1154 /* initialize thread stacksize */
1156 if (pthread_attr_setstacksize(&attr, opt_stacksize))
1157 vm_abort("pthread_attr_setstacksize failed: %s", strerror(errno));
1159 /* create the thread */
1161 if (pthread_create(&thread->tid, &attr, threads_startup_thread, &startup))
1162 vm_abort("pthread_create failed: %s", strerror(errno));
1164 /* signal that pthread_create has returned, so thread->tid is valid */
1166 threads_sem_post(&sem_first);
1168 /* wait here until the thread has entered itself into the thread list */
1170 threads_sem_wait(&sem);
1175 sem_destroy(&sem_first);
1179 /* threads_attach_current_thread ***********************************************
1181 Attaches the current thread to the VM. Used in JNI.
1183 *******************************************************************************/
1185 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
1187 threadobject *thread;
1188 java_lang_Thread *t;
1190 java_lang_String *s;
1191 java_lang_ThreadGroup *group;
1192 java_objectheader *o;
1194 /* create a java.lang.VMThread object */
1196 thread = (threadobject *) builtin_new(class_java_lang_VMThread);
1201 threads_init_threadobject(&thread->o);
1202 threads_set_current_threadobject(thread);
1203 lock_init_execution_env(thread);
1205 /* insert the thread into the threadlist and the threads table */
1207 pthread_mutex_lock(&threadlistlock);
1209 thread->prev = mainthreadobj;
1210 thread->next = mainthreadobj->next;
1211 mainthreadobj->next = thread;
1212 thread->next->prev = thread;
1214 threads_table_add(thread);
1216 pthread_mutex_unlock(&threadlistlock);
1218 /* mark main thread as Java thread */
1220 thread->flags = THREAD_FLAG_JAVA;
1222 #if defined(ENABLE_INTRP)
1223 /* create interpreter stack */
1226 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1227 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
1231 /* create a java.lang.Thread object */
1233 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
1238 thread->o.thread = t;
1240 if (vm_aargs != NULL) {
1241 u = utf_new_char(vm_aargs->name);
1242 group = (java_lang_ThreadGroup *) vm_aargs->group;
1246 group = mainthreadobj->o.thread->group;
1249 s = javastring_new(u);
1251 o = (java_objectheader *) t;
1253 (void) vm_call_method(method_thread_init, o, thread, s, NORM_PRIORITY,
1259 /* store the thread group in the object */
1263 o = (java_objectheader *) group;
1265 (void) vm_call_method(method_threadgroup_add, o, t);
1274 /* threads_detach_thread *******************************************************
1276 Detaches the passed thread from the VM. Used in JNI.
1278 *******************************************************************************/
1280 bool threads_detach_thread(threadobject *thread)
1282 java_lang_Thread *t;
1283 java_lang_ThreadGroup *group;
1285 java_objectheader *o;
1287 /* Allow lock record pools to be used by other threads. They
1288 cannot be deleted so we'd better not waste them. */
1290 /* XXX We have to find a new way to free lock records */
1291 /* with the new locking algorithm. */
1292 /* lock_record_free_pools(thread->ee.lockrecordpools); */
1294 /* XXX implement uncaught exception stuff (like JamVM does) */
1296 /* remove thread from the thread group */
1298 t = thread->o.thread;
1301 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1303 if (group != NULL) {
1304 m = class_resolveclassmethod(group->header.vftbl->class,
1306 utf_java_lang_Thread__V,
1307 class_java_lang_ThreadGroup,
1313 o = (java_objectheader *) group;
1315 (void) vm_call_method(m, o, t);
1321 /* remove thread from thread list and threads table, do this
1324 pthread_mutex_lock(&threadlistlock);
1326 thread->next->prev = thread->prev;
1327 thread->prev->next = thread->next;
1329 threads_table_remove(thread);
1331 pthread_mutex_unlock(&threadlistlock);
1333 /* reset thread id (lock on joinmutex? TWISTI) */
1335 pthread_mutex_lock(&thread->joinmutex);
1337 pthread_mutex_unlock(&thread->joinmutex);
1339 /* tell everyone that a thread has finished */
1341 pthread_cond_broadcast(&thread->joincond);
1347 /* threads_find_non_daemon_thread **********************************************
1349 Helper function used by threads_join_all_threads for finding
1350 non-daemon threads that are still running.
1352 *******************************************************************************/
1354 /* At the end of the program, we wait for all running non-daemon
1357 static threadobject *threads_find_non_daemon_thread(threadobject *thread)
1359 while (thread != mainthreadobj) {
1360 if (!thread->o.thread->daemon)
1362 thread = thread->prev;
1369 /* threads_join_all_threads ****************************************************
1371 Join all non-daemon threads.
1373 *******************************************************************************/
1375 void threads_join_all_threads(void)
1377 threadobject *thread;
1379 pthread_mutex_lock(&threadlistlock);
1381 while ((thread = threads_find_non_daemon_thread(mainthreadobj->prev)) != NULL) {
1383 pthread_mutex_lock(&thread->joinmutex);
1385 pthread_mutex_unlock(&threadlistlock);
1388 pthread_cond_wait(&thread->joincond, &thread->joinmutex);
1390 pthread_mutex_unlock(&thread->joinmutex);
1392 pthread_mutex_lock(&threadlistlock);
1395 pthread_mutex_unlock(&threadlistlock);
1399 /* threads_timespec_earlier ****************************************************
1401 Return true if timespec tv1 is earlier than timespec tv2.
1404 tv1..........first timespec
1405 tv2..........second timespec
1408 true, if the first timespec is earlier
1410 *******************************************************************************/
1412 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1413 const struct timespec *tv2)
1415 return (tv1->tv_sec < tv2->tv_sec)
1417 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1421 /* threads_current_time_is_earlier_than ****************************************
1423 Check if the current time is earlier than the given timespec.
1426 tv...........the timespec to compare against
1429 true, if the current time is earlier
1431 *******************************************************************************/
1433 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1435 struct timeval tvnow;
1436 struct timespec tsnow;
1438 /* get current time */
1440 if (gettimeofday(&tvnow, NULL) != 0)
1441 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1443 /* convert it to a timespec */
1445 tsnow.tv_sec = tvnow.tv_sec;
1446 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1448 /* compare current time with the given timespec */
1450 return threads_timespec_earlier(&tsnow, tv);
1454 /* threads_wait_with_timeout ***************************************************
1456 Wait until the given point in time on a monitor until either
1457 we are notified, we are interrupted, or the time is up.
1460 t............the current thread
1461 wakeupTime...absolute (latest) wakeup time
1462 If both tv_sec and tv_nsec are zero, this function
1463 waits for an unlimited amount of time.
1466 true.........if the wait has been interrupted,
1467 false........if the wait was ended by notification or timeout
1469 *******************************************************************************/
1471 static bool threads_wait_with_timeout(threadobject *t,
1472 struct timespec *wakeupTime)
1474 bool wasinterrupted;
1476 /* acquire the waitmutex */
1478 pthread_mutex_lock(&t->waitmutex);
1480 /* mark us as sleeping */
1484 /* wait on waitcond */
1486 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1488 while (!t->interrupted && !t->signaled
1489 && threads_current_time_is_earlier_than(wakeupTime))
1491 pthread_cond_timedwait(&t->waitcond, &t->waitmutex, wakeupTime);
1496 while (!t->interrupted && !t->signaled)
1497 pthread_cond_wait(&t->waitcond, &t->waitmutex);
1500 /* check if we were interrupted */
1502 wasinterrupted = t->interrupted;
1504 /* reset all flags */
1506 t->interrupted = false;
1507 t->signaled = false;
1508 t->sleeping = false;
1510 /* release the waitmutex */
1512 pthread_mutex_unlock(&t->waitmutex);
1514 return wasinterrupted;
1518 /* threads_wait_with_timeout_relative ******************************************
1520 Wait for the given maximum amount of time on a monitor until either
1521 we are notified, we are interrupted, or the time is up.
1524 t............the current thread
1525 millis.......milliseconds to wait
1526 nanos........nanoseconds to wait
1529 true.........if the wait has been interrupted,
1530 false........if the wait was ended by notification or timeout
1532 *******************************************************************************/
1534 bool threads_wait_with_timeout_relative(threadobject *t,
1538 struct timespec wakeupTime;
1540 /* calculate the the (latest) wakeup time */
1542 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1546 return threads_wait_with_timeout(t, &wakeupTime);
1550 /* threads_calc_absolute_time **************************************************
1552 Calculate the absolute point in time a given number of ms and ns from now.
1555 millis............milliseconds from now
1556 nanos.............nanoseconds from now
1559 *tm...............receives the timespec of the absolute point in time
1561 *******************************************************************************/
1563 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1565 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1568 gettimeofday(&tv, NULL);
1569 tv.tv_sec += millis / 1000;
1571 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1572 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1573 tm->tv_nsec = nsec % 1000000000;
1582 /* threads_thread_interrupt ****************************************************
1584 Interrupt the given thread.
1586 The thread gets the "waitcond" signal and
1587 its interrupted flag is set to true.
1590 thread............the thread to interrupt
1592 *******************************************************************************/
1594 void threads_thread_interrupt(java_lang_VMThread *thread)
1598 t = (threadobject *) thread;
1600 /* Signal the thread a "waitcond" and tell it that it has been
1603 pthread_mutex_lock(&t->waitmutex);
1605 /* Interrupt blocking system call using a signal. */
1607 pthread_kill(t->tid, SIGHUP);
1610 pthread_cond_signal(&t->waitcond);
1612 t->interrupted = true;
1614 pthread_mutex_unlock(&t->waitmutex);
1618 /* threads_check_if_interrupted_and_reset **************************************
1620 Check if the current thread has been interrupted and reset the
1624 true, if the current thread had been interrupted
1626 *******************************************************************************/
1628 bool threads_check_if_interrupted_and_reset(void)
1633 t = (threadobject*) THREADOBJECT;
1635 intr = t->interrupted;
1637 t->interrupted = false;
1643 /* threads_thread_has_been_interrupted *********************************************************
1645 Check if the given thread has been interrupted
1648 t............the thread to check
1651 true, if the given thread had been interrupted
1653 *******************************************************************************/
1655 bool threads_thread_has_been_interrupted(java_lang_VMThread *thread)
1659 t = (threadobject*) thread;
1661 return t->interrupted;
1665 /* threads_sleep ***************************************************************
1667 Sleep the current thread for the specified amount of time.
1669 *******************************************************************************/
1671 void threads_sleep(s8 millis, s4 nanos)
1674 struct timespec wakeupTime;
1675 bool wasinterrupted;
1677 t = (threadobject *) THREADOBJECT;
1679 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1681 wasinterrupted = threads_wait_with_timeout(t, &wakeupTime);
1684 *exceptionptr = new_exception(string_java_lang_InterruptedException);
1688 /* threads_yield ***************************************************************
1690 Yield to the scheduler.
1692 *******************************************************************************/
1694 void threads_yield(void)
1700 /* threads_java_lang_Thread_set_priority ***************************************
1702 Set the priority for the given java.lang.Thread.
1705 t............the java.lang.Thread
1706 priority.....the priority
1708 *******************************************************************************/
1710 void threads_java_lang_Thread_set_priority(java_lang_Thread *t, s4 priority)
1712 threadobject *thread;
1714 thread = (threadobject*) t->vmThread;
1716 threads_set_thread_priority(thread->tid, priority);
1720 /* threads_dump ****************************************************************
1722 Dumps info for all threads running in the JVM. This function is
1723 called when SIGQUIT (<ctrl>-\) is sent to CACAO.
1725 *******************************************************************************/
1727 void threads_dump(void)
1729 threadobject *thread;
1730 java_lang_VMThread *vmt;
1731 java_lang_Thread *t;
1734 thread = mainthreadobj;
1736 /* XXX we should stop the world here */
1738 printf("Full thread dump CACAO "VERSION":\n");
1740 /* iterate over all started threads */
1743 /* get thread objects */
1748 /* the thread may be currently in initalization, don't print it */
1751 /* get thread name */
1753 name = javastring_toutf(t->name, false);
1756 utf_display_printable_ascii(name);
1762 #if SIZEOF_VOID_P == 8
1763 printf("prio=%d tid=0x%016lx\n", t->priority, (long) thread->tid);
1765 printf("prio=%d tid=0x%08lx\n", t->priority, (long) thread->tid);
1768 /* dump trace of thread */
1770 stacktrace_dump_trace(thread);
1773 thread = thread->next;
1774 } while ((thread != NULL) && (thread != mainthreadobj));
1778 /* threads_table_dump *********************************************************
1780 Dump the threads table for debugging purposes.
1783 file..............stream to write to
1785 ******************************************************************************/
1787 #if !defined(NDEBUG) && 0
1788 static void threads_table_dump(FILE *file)
1794 pthread_mutex_lock(&threadlistlock);
1796 size = threads_table.size;
1798 fprintf(file, "======== THREADS TABLE (size %d) ========\n", size);
1800 for (i=0; i<size; ++i) {
1801 index = threads_table.table[i].nextfree;
1803 fprintf(file, "%4d: ", i);
1806 fprintf(file, "free, nextfree = %d\n", (int) index);
1809 fprintf(file, "thread %p\n", (void*) threads_table.table[i].thread);
1813 fprintf(file, "======== END OF THREADS TABLE ========\n");
1815 pthread_mutex_unlock(&threadlistlock);
1820 * These are local overrides for various environment variables in Emacs.
1821 * Please do not remove this and leave it at the end of the file, where
1822 * Emacs will automagically detect them.
1823 * ---------------------------------------------------------------------
1826 * indent-tabs-mode: t
1830 * vim:noexpandtab:sw=4:ts=4: