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 7587 2007-03-28 13:29:09Z twisti $
32 /* XXX cleanup these includes */
37 #include <sys/types.h>
50 #if !defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
51 # include "machine-instr.h"
53 # include "threads/native/generic-primitives.h"
56 #include "mm/gc-common.h"
57 #include "mm/memory.h"
59 #include "native/jni.h"
60 #include "native/native.h"
61 #include "native/include/java_lang_Object.h"
62 #include "native/include/java_lang_String.h"
63 #include "native/include/java_lang_Throwable.h"
64 #include "native/include/java_lang_Thread.h"
66 #if defined(ENABLE_JAVASE)
67 # include "native/include/java_lang_ThreadGroup.h"
70 #if defined(WITH_CLASSPATH_GNU)
71 # include "native/include/java_lang_VMThread.h"
74 #include "threads/threads-common.h"
76 #include "threads/native/threads.h"
78 #include "toolbox/avl.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
192 #define THREADS_INITIAL_TABLE_SIZE 8
195 /* startupinfo *****************************************************************
197 Struct used to pass info from threads_start_thread to
198 threads_startup_thread.
200 ******************************************************************************/
203 threadobject *thread; /* threadobject for this thread */
204 functionptr function; /* function to run in the new thread */
205 sem_t *psem; /* signals when thread has been entered */
206 /* in the thread list */
207 sem_t *psem_first; /* signals when pthread_create has returned */
211 /* prototypes *****************************************************************/
213 static void threads_table_init(void);
214 static s4 threads_table_add(threadobject *thread);
215 static void threads_table_remove(threadobject *thread);
216 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
218 #if !defined(NDEBUG) && 0
219 static void threads_table_dump(FILE *file);
222 /******************************************************************************/
223 /* GLOBAL VARIABLES */
224 /******************************************************************************/
226 /* the main thread */
227 threadobject *mainthreadobj;
229 static methodinfo *method_thread_init;
231 /* the thread object of the current thread */
232 /* This is either a thread-local variable defined with __thread, or */
233 /* a thread-specific value stored with key threads_current_threadobject_key. */
234 #if defined(HAVE___THREAD)
235 __thread threadobject *threads_current_threadobject;
237 pthread_key_t threads_current_threadobject_key;
240 /* global threads table */
241 static threads_table_t threads_table;
243 /* global compiler mutex */
244 static pthread_mutex_t compiler_mutex;
246 /* global mutex for changing the thread list */
247 static pthread_mutex_t threadlistlock;
249 /* global mutex for stop-the-world */
250 static pthread_mutex_t stopworldlock;
252 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
254 static volatile int stopworldwhere;
256 /* semaphore used for acknowleding thread suspension */
257 static sem_t suspend_ack;
258 #if defined(__MIPS__)
259 static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
260 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
263 static pthread_attr_t threadattr;
265 /* mutexes used by the fake atomic instructions */
266 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
267 pthread_mutex_t _atomic_add_lock = PTHREAD_MUTEX_INITIALIZER;
268 pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
269 pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
273 /* threads_sem_init ************************************************************
275 Initialize a semaphore. Checks against errors and interruptions.
278 sem..............the semaphore to initialize
279 shared...........true if this semaphore will be shared between processes
280 value............the initial value for the semaphore
282 *******************************************************************************/
284 void threads_sem_init(sem_t *sem, bool shared, int value)
291 r = sem_init(sem, shared, value);
294 } while (errno == EINTR);
296 vm_abort("sem_init failed: %s", strerror(errno));
300 /* threads_sem_wait ************************************************************
302 Wait for a semaphore, non-interruptible.
304 IMPORTANT: Always use this function instead of `sem_wait` directly, as
305 `sem_wait` may be interrupted by signals!
308 sem..............the semaphore to wait on
310 *******************************************************************************/
312 void threads_sem_wait(sem_t *sem)
322 } while (errno == EINTR);
324 vm_abort("sem_wait failed: %s", strerror(errno));
328 /* threads_sem_post ************************************************************
330 Increase the count of a semaphore. Checks for errors.
333 sem..............the semaphore to increase the count of
335 *******************************************************************************/
337 void threads_sem_post(sem_t *sem)
343 /* unlike sem_wait, sem_post is not interruptible */
349 vm_abort("sem_post failed: %s", strerror(errno));
353 /* compiler_lock ***************************************************************
355 Enter the compiler lock.
357 ******************************************************************************/
359 void compiler_lock(void)
361 pthread_mutex_lock(&compiler_mutex);
365 /* compiler_unlock *************************************************************
367 Release the compiler lock.
369 ******************************************************************************/
371 void compiler_unlock(void)
373 pthread_mutex_unlock(&compiler_mutex);
377 /* lock_stopworld **************************************************************
379 Enter the stopworld lock, specifying why the world shall be stopped.
382 where........ STOPWORLD_FROM_GC (1) from within GC
383 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
385 ******************************************************************************/
387 void lock_stopworld(int where)
389 pthread_mutex_lock(&stopworldlock);
390 stopworldwhere = where;
394 /* unlock_stopworld ************************************************************
396 Release the stopworld lock.
398 ******************************************************************************/
400 void unlock_stopworld(void)
403 pthread_mutex_unlock(&stopworldlock);
406 #if !defined(__DARWIN__)
407 /* Caller must hold threadlistlock */
408 static int threads_cast_sendsignals(int sig, int count)
411 threadobject *tobj = mainthreadobj;
412 threadobject *self = THREADOBJECT;
418 } while (tobj != mainthreadobj);
421 assert(tobj == mainthreadobj);
425 pthread_kill(tobj->tid, sig);
427 } while (tobj != mainthreadobj);
434 static void threads_cast_darwinstop(void)
436 threadobject *tobj = mainthreadobj;
437 threadobject *self = THREADOBJECT;
442 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
443 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
444 #if defined(__I386__)
445 i386_thread_state_t thread_state;
447 ppc_thread_state_t thread_state;
449 mach_port_t thread = tobj->mach_thread;
452 r = thread_suspend(thread);
454 if (r != KERN_SUCCESS)
455 vm_abort("thread_suspend failed");
457 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
458 &thread_state_count);
460 if (r != KERN_SUCCESS)
461 vm_abort("thread_get_state failed");
463 thread_restartcriticalsection((ucontext_t *) &thread_state);
465 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
468 if (r != KERN_SUCCESS)
469 vm_abort("thread_set_state failed");
473 } while (tobj != mainthreadobj);
476 static void threads_cast_darwinresume(void)
478 threadobject *tobj = mainthreadobj;
479 threadobject *self = THREADOBJECT;
484 mach_port_t thread = tobj->mach_thread;
487 r = thread_resume(thread);
489 if (r != KERN_SUCCESS)
490 vm_abort("thread_resume failed");
494 } while (tobj != mainthreadobj);
499 #if defined(__MIPS__)
500 static void threads_cast_irixresume(void)
502 pthread_mutex_lock(&suspend_ack_lock);
503 pthread_cond_broadcast(&suspend_cond);
504 pthread_mutex_unlock(&suspend_ack_lock);
508 #if !defined(DISABLE_GC)
510 void threads_cast_stopworld(void)
512 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
516 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
517 pthread_mutex_lock(&threadlistlock);
519 #if defined(__DARWIN__)
520 threads_cast_darwinstop();
521 #elif defined(__CYGWIN__)
525 count = threads_cast_sendsignals(GC_signum1(), 0);
526 for (i = 0; i < count; i++)
527 threads_sem_wait(&suspend_ack);
530 pthread_mutex_unlock(&threadlistlock);
533 void threads_cast_startworld(void)
535 pthread_mutex_lock(&threadlistlock);
536 #if defined(__DARWIN__)
537 threads_cast_darwinresume();
538 #elif defined(__MIPS__)
539 threads_cast_irixresume();
540 #elif defined(__CYGWIN__)
544 threads_cast_sendsignals(GC_signum2(), -1);
546 pthread_mutex_unlock(&threadlistlock);
551 #if !defined(__DARWIN__)
552 static void threads_sigsuspend_handler(ucontext_t *ctx)
557 /* XXX TWISTI: this is just a quick hack */
558 #if defined(ENABLE_JIT)
559 thread_restartcriticalsection(ctx);
562 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
563 (not POSIX async-safe). */
564 #if defined(__IRIX__)
565 pthread_mutex_lock(&suspend_ack_lock);
566 threads_sem_post(&suspend_ack);
567 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
568 pthread_mutex_unlock(&suspend_ack_lock);
569 #elif defined(__CYGWIN__)
573 threads_sem_post(&suspend_ack);
577 sigdelset(&sigs, sig);
582 /* This function is called from Boehm GC code. */
584 int cacao_suspendhandler(ucontext_t *ctx)
586 if (stopworldwhere != STOPWORLD_FROM_CLASS_NUMBERING)
589 threads_sigsuspend_handler(ctx);
594 #endif /* DISABLE_GC */
596 /* threads_set_current_threadobject ********************************************
598 Set the current thread object.
601 thread.......the thread object to set
603 *******************************************************************************/
605 static void threads_set_current_threadobject(threadobject *thread)
607 #if !defined(HAVE___THREAD)
608 pthread_setspecific(threads_current_threadobject_key, thread);
610 threads_current_threadobject = thread;
615 /* threads_init_threadobject **************************************************
617 Initialize implementation fields of a threadobject.
620 thread............the threadobject
622 ******************************************************************************/
624 static void threads_init_threadobject(threadobject *thread)
626 thread->tid = pthread_self();
630 /* TODO destroy all those things */
631 pthread_mutex_init(&(thread->joinmutex), NULL);
632 pthread_cond_init(&(thread->joincond), NULL);
634 pthread_mutex_init(&(thread->waitmutex), NULL);
635 pthread_cond_init(&(thread->waitcond), NULL);
637 thread->interrupted = false;
638 thread->signaled = false;
639 thread->sleeping = false;
643 /* threads_get_current_threadobject ********************************************
645 Return the threadobject of the current thread.
648 the current threadobject * (an instance of java.lang.Thread)
650 *******************************************************************************/
652 threadobject *threads_get_current_threadobject(void)
658 /* threads_preinit *************************************************************
660 Do some early initialization of stuff required.
662 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
663 is called AFTER this function!
665 *******************************************************************************/
667 void threads_preinit(void)
669 pthread_mutexattr_t mutexattr;
670 pthread_mutexattr_init(&mutexattr);
671 pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
672 pthread_mutex_init(&compiler_mutex, &mutexattr);
673 pthread_mutexattr_destroy(&mutexattr);
675 pthread_mutex_init(&threadlistlock, NULL);
676 pthread_mutex_init(&stopworldlock, NULL);
678 mainthreadobj = NEW(threadobject);
680 #if defined(ENABLE_STATISTICS)
682 size_threadobject += sizeof(threadobject);
685 mainthreadobj->object = NULL;
686 mainthreadobj->tid = pthread_self();
687 mainthreadobj->index = 1;
688 mainthreadobj->thinlock = lock_pre_compute_thinlock(mainthreadobj->index);
690 #if !defined(HAVE___THREAD)
691 pthread_key_create(&threads_current_threadobject_key, NULL);
693 threads_set_current_threadobject(mainthreadobj);
695 threads_sem_init(&suspend_ack, 0, 0);
697 /* initialize the threads table */
699 threads_table_init();
701 /* initialize subsystems */
709 /* threads_init ****************************************************************
711 Initializes the threads required by the JVM: main, finalizer.
713 *******************************************************************************/
715 bool threads_init(void)
717 java_lang_String *threadname;
718 threadobject *tempthread;
719 java_objectheader *o;
721 #if defined(ENABLE_JAVASE)
722 java_lang_ThreadGroup *threadgroup;
727 #if defined(WITH_CLASSPATH_GNU)
728 java_lang_VMThread *vmt;
731 tempthread = mainthreadobj;
733 /* XXX We have to find a new way to free lock records */
734 /* with the new locking algorithm. */
735 /* lock_record_free_pools(mainthreadobj->ee.lockrecordpools); */
738 /* This is kinda tricky, we grow the java.lang.Thread object so we
739 can keep the execution environment there. No Thread object must
740 have been created at an earlier time. */
742 class_java_lang_Thread->instancesize = sizeof(threadobject);
745 /* get methods we need in this file */
747 #if defined(WITH_CLASSPATH_GNU)
749 class_resolveclassmethod(class_java_lang_Thread,
751 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
752 class_java_lang_Thread,
756 class_resolveclassmethod(class_java_lang_Thread,
758 utf_new_char("(Ljava/lang/String;)V"),
759 class_java_lang_Thread,
763 if (method_thread_init == NULL)
766 /* create a vm internal thread object for the main thread */
767 /* XXX Michi: we do not need to do this here, we could use the one
768 created by threads_preinit() */
770 #if defined(ENABLE_GC_CACAO)
771 mainthreadobj = NEW(threadobject);
773 # if defined(ENABLE_STATISTICS)
775 size_threadobject += sizeof(threadobject);
778 mainthreadobj = GCNEW(threadobject);
781 if (mainthreadobj == NULL)
784 /* create a java.lang.Thread for the main thread */
786 mainthreadobj->object = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
788 if (mainthreadobj->object == NULL)
791 FREE(tempthread, threadobject);
793 threads_init_threadobject(mainthreadobj);
795 threads_set_current_threadobject(mainthreadobj);
797 lock_init_execution_env(mainthreadobj);
799 mainthreadobj->next = mainthreadobj;
800 mainthreadobj->prev = mainthreadobj;
802 threads_table_add(mainthreadobj);
804 /* mark main thread as Java thread */
806 mainthreadobj->flags = THREAD_FLAG_JAVA;
808 #if defined(ENABLE_INTRP)
809 /* create interpreter stack */
812 MSET(intrp_main_stack, 0, u1, opt_stacksize);
813 mainthreadobj->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
817 threadname = javastring_new(utf_new_char("main"));
819 #if defined(ENABLE_JAVASE)
820 /* allocate and init ThreadGroup */
822 threadgroup = (java_lang_ThreadGroup *)
823 native_new_and_init(class_java_lang_ThreadGroup);
825 if (threadgroup == NULL)
829 #if defined(WITH_CLASSPATH_GNU)
830 /* create a java.lang.VMThread for the main thread */
832 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
839 vmt->thread = mainthreadobj->object;
840 vmt->vmdata = (java_lang_Object *) mainthreadobj;
842 /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
843 o = (java_objectheader *) mainthreadobj->object;
845 (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
847 #elif defined(WITH_CLASSPATH_CLDC1_1)
850 mainthreadobj->object->vm_thread = (java_lang_Object *) mainthreadobj;
852 /* call public Thread(String name) */
854 o = (java_objectheader *) mainthreadobj->object;
856 (void) vm_call_method(method_thread_init, o, threadname);
862 #if defined(ENABLE_JAVASE)
863 mainthreadobj->object->group = threadgroup;
865 /* add main thread to java.lang.ThreadGroup */
867 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
869 utf_java_lang_Thread__V,
870 class_java_lang_ThreadGroup,
873 o = (java_objectheader *) threadgroup;
874 t = mainthreadobj->object;
876 (void) vm_call_method(m, o, t);
883 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
885 /* initialize the thread attribute object */
887 if (pthread_attr_init(&threadattr)) {
888 log_println("pthread_attr_init failed: %s", strerror(errno));
892 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
894 /* everything's ok */
900 /* threads_table_init *********************************************************
902 Initialize the global threads table.
904 ******************************************************************************/
906 static void threads_table_init(void)
911 size = THREADS_INITIAL_TABLE_SIZE;
913 threads_table.size = size;
914 threads_table.table = MNEW(threads_table_entry_t, size);
916 /* link the entries in a freelist */
918 for (i=0; i<size; ++i) {
919 threads_table.table[i].nextfree = i+1;
922 /* terminate the freelist */
924 threads_table.table[size-1].nextfree = 0; /* index 0 is never free */
928 /* threads_table_add **********************************************************
930 Add a thread to the global threads table. The index is entered in the
931 threadobject. The thinlock value for the thread is pre-computed.
934 thread............the thread to add
937 The table index for the newly added thread. This value has also been
938 entered in the threadobject.
941 The caller must hold the threadlistlock!
943 ******************************************************************************/
945 static s4 threads_table_add(threadobject *thread)
952 /* table[0] serves as the head of the freelist */
954 index = threads_table.table[0].nextfree;
956 /* if we got a free index, use it */
960 threads_table.table[0].nextfree = threads_table.table[index].nextfree;
961 threads_table.table[index].thread = thread;
962 thread->index = index;
963 thread->thinlock = lock_pre_compute_thinlock(index);
967 /* we must grow the table */
969 oldsize = threads_table.size;
970 newsize = oldsize * 2;
972 threads_table.table = MREALLOC(threads_table.table, threads_table_entry_t,
974 threads_table.size = newsize;
976 /* link the new entries to a free list */
978 for (i=oldsize; i<newsize; ++i) {
979 threads_table.table[i].nextfree = i+1;
982 /* terminate the freelist */
984 threads_table.table[newsize-1].nextfree = 0; /* index 0 is never free */
986 /* use the first of the new entries */
993 /* threads_table_remove *******************************************************
995 Remove a thread from the global threads table.
998 thread............the thread to remove
1001 The caller must hold the threadlistlock!
1003 ******************************************************************************/
1005 static void threads_table_remove(threadobject *thread)
1009 index = thread->index;
1011 /* put the index into the freelist */
1013 threads_table.table[index] = threads_table.table[0];
1014 threads_table.table[0].nextfree = index;
1016 /* delete the index in the threadobject to discover bugs */
1017 #if !defined(NDEBUG)
1023 /* threads_startup_thread ******************************************************
1025 Thread startup function called by pthread_create.
1027 Thread which have a startup.function != NULL are marked as internal
1028 threads. All other threads are threated as normal Java threads.
1030 NOTE: This function is not called directly by pthread_create. The Boehm GC
1031 inserts its own GC_start_routine in between, which then calls
1035 t............the argument passed to pthread_create, ie. a pointer to
1036 a startupinfo struct. CAUTION: When the `psem` semaphore
1037 is posted, the startupinfo struct becomes invalid! (It
1038 is allocated on the stack of threads_start_thread.)
1040 ******************************************************************************/
1042 static void *threads_startup_thread(void *t)
1044 startupinfo *startup;
1045 threadobject *thread;
1046 #if defined(WITH_CLASSPATH_GNU)
1047 java_lang_VMThread *vmt;
1050 threadobject *tnext;
1053 java_objectheader *o;
1054 functionptr function;
1056 #if defined(ENABLE_INTRP)
1057 u1 *intrp_thread_stack;
1059 /* create interpreter stack */
1062 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
1063 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
1066 intrp_thread_stack = NULL;
1069 /* get passed startupinfo structure and the values in there */
1072 t = NULL; /* make sure it's not used wrongly */
1074 thread = startup->thread;
1075 function = startup->function;
1076 psem = startup->psem;
1078 /* Seems like we've encountered a situation where thread->tid was not set by
1079 * pthread_create. We alleviate this problem by waiting for pthread_create
1081 threads_sem_wait(startup->psem_first);
1083 /* set the thread object */
1085 #if defined(__DARWIN__)
1086 thread->mach_thread = mach_thread_self();
1088 threads_set_current_threadobject(thread);
1090 /* insert the thread into the threadlist and the threads table */
1092 pthread_mutex_lock(&threadlistlock);
1094 thread->prev = mainthreadobj;
1095 thread->next = tnext = mainthreadobj->next;
1096 mainthreadobj->next = thread;
1097 tnext->prev = thread;
1099 threads_table_add(thread);
1101 pthread_mutex_unlock(&threadlistlock);
1103 /* init data structures of this thread */
1105 lock_init_execution_env(thread);
1107 /* tell threads_startup_thread that we registered ourselves */
1108 /* CAUTION: *startup becomes invalid with this! */
1111 threads_sem_post(psem);
1113 /* set our priority */
1115 threads_set_thread_priority(thread->tid, thread->object->priority);
1117 #if defined(ENABLE_INTRP)
1118 /* set interpreter stack */
1121 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1124 #if defined(ENABLE_JVMTI)
1125 /* fire thread start event */
1128 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1131 /* find and run the Thread.run()V method if no other function was passed */
1133 if (function == NULL) {
1134 /* this is a normal Java thread */
1136 thread->flags |= THREAD_FLAG_JAVA;
1138 #if defined(WITH_CLASSPATH_GNU)
1139 /* We need to start the run method of
1140 java.lang.VMThread. Since this is a final class, we can use
1141 the class object directly. */
1143 c = class_java_lang_VMThread;
1144 #elif defined(WITH_CLASSPATH_CLDC1_1)
1145 c = thread->object->header.vftbl->class;
1148 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1151 vm_abort("threads_startup_thread: run() method not found in class");
1153 /* set ThreadMXBean variables */
1155 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1156 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1158 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1159 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1160 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1161 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1163 #if defined(WITH_CLASSPATH_GNU)
1164 /* we need to start the run method of java.lang.VMThread */
1166 vmt = (java_lang_VMThread *) thread->object->vmThread;
1167 o = (java_objectheader *) vmt;
1169 #elif defined(WITH_CLASSPATH_CLDC1_1)
1170 o = (java_objectheader *) thread->object;
1173 (void) vm_call_method(m, o);
1176 /* this is an internal thread */
1178 thread->flags |= THREAD_FLAG_INTERNAL;
1180 /* set ThreadMXBean variables */
1182 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1183 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1185 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1186 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1187 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1188 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1190 /* call passed function, e.g. finalizer_thread */
1195 #if defined(ENABLE_JVMTI)
1196 /* fire thread end event */
1199 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1202 threads_detach_thread(thread);
1204 /* set ThreadMXBean variables */
1206 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1212 /* threads_start_javathread ***************************************************
1214 Start a thread in the JVM. Only the java thread object exists so far.
1217 object.....the java thread object java.lang.Thread
1219 ******************************************************************************/
1221 void threads_start_javathread(java_lang_Thread *object)
1223 threadobject *thread;
1225 /* create the vm internal threadobject */
1227 thread = NEW(threadobject);
1229 #if defined(ENABLE_STATISTICS)
1231 size_threadobject += sizeof(threadobject);
1234 /* link the two objects together */
1236 thread->object = object;
1238 #if defined(WITH_CLASSPATH_GNU)
1239 assert(object->vmThread);
1240 assert(object->vmThread->vmdata == NULL);
1241 object->vmThread->vmdata = (java_lang_Object *) thread;
1242 #elif defined(WITH_CLASSPATH_CLDC1_1)
1243 object->vm_thread = (java_lang_Object *) thread;
1246 /* actually start the thread */
1247 /* don't pass a function pointer (NULL) since we want Thread.run()V here */
1249 threads_start_thread(thread, NULL);
1253 /* threads_start_thread ********************************************************
1255 Start a thread in the JVM. Both (vm internal and java) thread objects exist.
1258 thread.......the thread object
1259 function.....function to run in the new thread. NULL means that the
1260 "run" method of the object `t` should be called
1262 ******************************************************************************/
1264 void threads_start_thread(threadobject *thread, functionptr function)
1268 pthread_attr_t attr;
1269 startupinfo startup;
1271 /* fill startupinfo structure passed by pthread_create to
1272 * threads_startup_thread */
1274 startup.thread = thread;
1275 startup.function = function; /* maybe we don't call Thread.run()V */
1276 startup.psem = &sem;
1277 startup.psem_first = &sem_first;
1279 threads_sem_init(&sem, 0, 0);
1280 threads_sem_init(&sem_first, 0, 0);
1282 /* initialize thread attribute object */
1284 if (pthread_attr_init(&attr))
1285 vm_abort("pthread_attr_init failed: %s", strerror(errno));
1287 /* initialize thread stacksize */
1289 if (pthread_attr_setstacksize(&attr, opt_stacksize))
1290 vm_abort("pthread_attr_setstacksize failed: %s", strerror(errno));
1292 /* create the thread */
1294 if (pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup))
1295 vm_abort("pthread_create failed: %s", strerror(errno));
1297 /* signal that pthread_create has returned, so thread->tid is valid */
1299 threads_sem_post(&sem_first);
1301 /* wait here until the thread has entered itself into the thread list */
1303 threads_sem_wait(&sem);
1308 sem_destroy(&sem_first);
1312 /* threads_set_thread_priority *************************************************
1314 Set the priority of the given thread.
1317 tid..........thread id
1318 priority.....priority to set
1320 ******************************************************************************/
1322 void threads_set_thread_priority(pthread_t tid, int priority)
1324 struct sched_param schedp;
1327 pthread_getschedparam(tid, &policy, &schedp);
1328 schedp.sched_priority = priority;
1329 pthread_setschedparam(tid, policy, &schedp);
1333 /* threads_attach_current_thread ***********************************************
1335 Attaches the current thread to the VM. Used in JNI.
1337 *******************************************************************************/
1339 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
1341 threadobject *thread;
1343 java_lang_String *s;
1344 java_objectheader *o;
1345 java_lang_Thread *t;
1347 #if defined(ENABLE_JAVASE)
1348 java_lang_ThreadGroup *group;
1352 #if defined(WITH_CLASSPATH_GNU)
1353 java_lang_VMThread *vmt;
1356 /* create a vm internal thread object */
1358 thread = NEW(threadobject);
1360 #if defined(ENABLE_STATISTICS)
1362 size_threadobject += sizeof(threadobject);
1368 /* create a java.lang.Thread object */
1370 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
1377 threads_init_threadobject(thread);
1378 threads_set_current_threadobject(thread);
1379 lock_init_execution_env(thread);
1381 /* insert the thread into the threadlist and the threads table */
1383 pthread_mutex_lock(&threadlistlock);
1385 thread->prev = mainthreadobj;
1386 thread->next = mainthreadobj->next;
1387 mainthreadobj->next = thread;
1388 thread->next->prev = thread;
1390 threads_table_add(thread);
1392 pthread_mutex_unlock(&threadlistlock);
1394 /* mark thread as Java thread */
1396 thread->flags = THREAD_FLAG_JAVA;
1399 thread->flags |= THREAD_FLAG_DAEMON;
1401 #if defined(ENABLE_INTRP)
1402 /* create interpreter stack */
1405 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1406 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
1410 #if defined(WITH_CLASSPATH_GNU)
1411 /* create a java.lang.VMThread object */
1413 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
1418 /* set the thread */
1421 vmt->vmdata = (java_lang_Object *) thread;
1422 #elif defined(WITH_CLASSPATH_CLDC1_1)
1423 t->vm_thread = (java_lang_Object *) thread;
1426 if (vm_aargs != NULL) {
1427 u = utf_new_char(vm_aargs->name);
1428 #if defined(ENABLE_JAVASE)
1429 group = (java_lang_ThreadGroup *) vm_aargs->group;
1434 #if defined(ENABLE_JAVASE)
1435 group = mainthreadobj->object->group;
1439 s = javastring_new(u);
1441 o = (java_objectheader *) thread->object;
1443 #if defined(WITH_CLASSPATH_GNU)
1444 (void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
1446 #elif defined(WITH_CLASSPATH_CLDC1_1)
1447 (void) vm_call_method(method_thread_init, o, s);
1453 #if defined(ENABLE_JAVASE)
1454 /* store the thread group in the object */
1456 thread->object->group = group;
1458 /* add thread to given thread-group */
1460 m = class_resolveclassmethod(group->header.vftbl->class,
1462 utf_java_lang_Thread__V,
1463 class_java_lang_ThreadGroup,
1466 o = (java_objectheader *) group;
1468 (void) vm_call_method(m, o, t);
1478 /* threads_detach_thread *******************************************************
1480 Detaches the passed thread from the VM. Used in JNI.
1482 *******************************************************************************/
1484 bool threads_detach_thread(threadobject *thread)
1486 #if defined(ENABLE_JAVASE)
1487 java_lang_ThreadGroup *group;
1489 java_objectheader *o;
1490 java_lang_Thread *t;
1493 /* Allow lock record pools to be used by other threads. They
1494 cannot be deleted so we'd better not waste them. */
1496 /* XXX We have to find a new way to free lock records */
1497 /* with the new locking algorithm. */
1498 /* lock_record_free_pools(thread->ee.lockrecordpools); */
1500 /* XXX implement uncaught exception stuff (like JamVM does) */
1502 #if defined(ENABLE_JAVASE)
1503 /* remove thread from the thread group */
1505 group = thread->object->group;
1507 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1509 if (group != NULL) {
1510 m = class_resolveclassmethod(group->header.vftbl->class,
1512 utf_java_lang_Thread__V,
1513 class_java_lang_ThreadGroup,
1519 o = (java_objectheader *) group;
1522 (void) vm_call_method(m, o, t);
1529 /* remove thread from thread list and threads table, do this
1532 pthread_mutex_lock(&threadlistlock);
1534 thread->next->prev = thread->prev;
1535 thread->prev->next = thread->next;
1537 threads_table_remove(thread);
1539 pthread_mutex_unlock(&threadlistlock);
1541 /* reset thread id (lock on joinmutex? TWISTI) */
1543 pthread_mutex_lock(&(thread->joinmutex));
1545 pthread_mutex_unlock(&(thread->joinmutex));
1547 /* tell everyone that a thread has finished */
1549 pthread_cond_broadcast(&(thread->joincond));
1551 /* free the vm internal thread object */
1553 FREE(thread, threadobject);
1555 #if defined(ENABLE_STATISTICS)
1557 size_threadobject -= sizeof(threadobject);
1564 /* threads_find_non_daemon_thread **********************************************
1566 Helper function used by threads_join_all_threads for finding
1567 non-daemon threads that are still running.
1569 *******************************************************************************/
1571 /* At the end of the program, we wait for all running non-daemon
1574 static threadobject *threads_find_non_daemon_thread(threadobject *thread)
1576 while (thread != mainthreadobj) {
1577 if (!(thread->flags & THREAD_FLAG_DAEMON))
1580 thread = thread->prev;
1587 /* threads_join_all_threads ****************************************************
1589 Join all non-daemon threads.
1591 *******************************************************************************/
1593 void threads_join_all_threads(void)
1595 threadobject *thread;
1597 pthread_mutex_lock(&threadlistlock);
1599 while ((thread = threads_find_non_daemon_thread(mainthreadobj->prev)) != NULL) {
1600 pthread_mutex_lock(&(thread->joinmutex));
1602 pthread_mutex_unlock(&threadlistlock);
1605 pthread_cond_wait(&(thread->joincond), &(thread->joinmutex));
1607 pthread_mutex_unlock(&(thread->joinmutex));
1609 pthread_mutex_lock(&threadlistlock);
1612 pthread_mutex_unlock(&threadlistlock);
1616 /* threads_timespec_earlier ****************************************************
1618 Return true if timespec tv1 is earlier than timespec tv2.
1621 tv1..........first timespec
1622 tv2..........second timespec
1625 true, if the first timespec is earlier
1627 *******************************************************************************/
1629 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1630 const struct timespec *tv2)
1632 return (tv1->tv_sec < tv2->tv_sec)
1634 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1638 /* threads_current_time_is_earlier_than ****************************************
1640 Check if the current time is earlier than the given timespec.
1643 tv...........the timespec to compare against
1646 true, if the current time is earlier
1648 *******************************************************************************/
1650 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1652 struct timeval tvnow;
1653 struct timespec tsnow;
1655 /* get current time */
1657 if (gettimeofday(&tvnow, NULL) != 0)
1658 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1660 /* convert it to a timespec */
1662 tsnow.tv_sec = tvnow.tv_sec;
1663 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1665 /* compare current time with the given timespec */
1667 return threads_timespec_earlier(&tsnow, tv);
1671 /* threads_wait_with_timeout ***************************************************
1673 Wait until the given point in time on a monitor until either
1674 we are notified, we are interrupted, or the time is up.
1677 t............the current thread
1678 wakeupTime...absolute (latest) wakeup time
1679 If both tv_sec and tv_nsec are zero, this function
1680 waits for an unlimited amount of time.
1683 true.........if the wait has been interrupted,
1684 false........if the wait was ended by notification or timeout
1686 *******************************************************************************/
1688 static bool threads_wait_with_timeout(threadobject *thread,
1689 struct timespec *wakeupTime)
1691 bool wasinterrupted;
1693 /* acquire the waitmutex */
1695 pthread_mutex_lock(&thread->waitmutex);
1697 /* mark us as sleeping */
1699 thread->sleeping = true;
1701 /* wait on waitcond */
1703 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1705 while (!thread->interrupted && !thread->signaled
1706 && threads_current_time_is_earlier_than(wakeupTime))
1708 pthread_cond_timedwait(&thread->waitcond, &thread->waitmutex,
1714 while (!thread->interrupted && !thread->signaled)
1715 pthread_cond_wait(&thread->waitcond, &thread->waitmutex);
1718 /* check if we were interrupted */
1720 wasinterrupted = thread->interrupted;
1722 /* reset all flags */
1724 thread->interrupted = false;
1725 thread->signaled = false;
1726 thread->sleeping = false;
1728 /* release the waitmutex */
1730 pthread_mutex_unlock(&thread->waitmutex);
1732 return wasinterrupted;
1736 /* threads_wait_with_timeout_relative ******************************************
1738 Wait for the given maximum amount of time on a monitor until either
1739 we are notified, we are interrupted, or the time is up.
1742 t............the current thread
1743 millis.......milliseconds to wait
1744 nanos........nanoseconds to wait
1747 true.........if the wait has been interrupted,
1748 false........if the wait was ended by notification or timeout
1750 *******************************************************************************/
1752 bool threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1755 struct timespec wakeupTime;
1757 /* calculate the the (latest) wakeup time */
1759 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1763 return threads_wait_with_timeout(thread, &wakeupTime);
1767 /* threads_calc_absolute_time **************************************************
1769 Calculate the absolute point in time a given number of ms and ns from now.
1772 millis............milliseconds from now
1773 nanos.............nanoseconds from now
1776 *tm...............receives the timespec of the absolute point in time
1778 *******************************************************************************/
1780 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1782 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1785 gettimeofday(&tv, NULL);
1786 tv.tv_sec += millis / 1000;
1788 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1789 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1790 tm->tv_nsec = nsec % 1000000000;
1799 /* threads_thread_interrupt ****************************************************
1801 Interrupt the given thread.
1803 The thread gets the "waitcond" signal and
1804 its interrupted flag is set to true.
1807 thread............the thread to interrupt
1809 *******************************************************************************/
1811 void threads_thread_interrupt(threadobject *thread)
1813 /* Signal the thread a "waitcond" and tell it that it has been
1816 pthread_mutex_lock(&thread->waitmutex);
1818 /* Interrupt blocking system call using a signal. */
1820 pthread_kill(thread->tid, SIGHUP);
1822 if (thread->sleeping)
1823 pthread_cond_signal(&thread->waitcond);
1825 thread->interrupted = true;
1827 pthread_mutex_unlock(&thread->waitmutex);
1831 /* threads_check_if_interrupted_and_reset **************************************
1833 Check if the current thread has been interrupted and reset the
1837 true, if the current thread had been interrupted
1839 *******************************************************************************/
1841 bool threads_check_if_interrupted_and_reset(void)
1843 threadobject *thread;
1846 thread = THREADOBJECT;
1848 /* get interrupted flag */
1850 intr = thread->interrupted;
1852 /* reset interrupted flag */
1854 thread->interrupted = false;
1860 /* threads_thread_has_been_interrupted *****************************************
1862 Check if the given thread has been interrupted
1865 t............the thread to check
1868 true, if the given thread had been interrupted
1870 *******************************************************************************/
1872 bool threads_thread_has_been_interrupted(threadobject *thread)
1874 return thread->interrupted;
1878 /* threads_sleep ***************************************************************
1880 Sleep the current thread for the specified amount of time.
1882 *******************************************************************************/
1884 void threads_sleep(s8 millis, s4 nanos)
1886 threadobject *thread;
1887 struct timespec wakeupTime;
1888 bool wasinterrupted;
1890 thread = THREADOBJECT;
1892 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1894 wasinterrupted = threads_wait_with_timeout(thread, &wakeupTime);
1897 exceptions_throw_interruptedexception();
1901 /* threads_yield ***************************************************************
1903 Yield to the scheduler.
1905 *******************************************************************************/
1907 void threads_yield(void)
1913 /* threads_dump ****************************************************************
1915 Dumps info for all threads running in the JVM. This function is
1916 called when SIGQUIT (<ctrl>-\) is sent to CACAO.
1918 *******************************************************************************/
1920 void threads_dump(void)
1922 threadobject *thread;
1923 java_lang_Thread *t;
1926 thread = mainthreadobj;
1928 /* XXX we should stop the world here */
1930 printf("Full thread dump CACAO "VERSION":\n");
1932 /* iterate over all started threads */
1935 /* get thread object */
1939 /* the thread may be currently in initalization, don't print it */
1942 /* get thread name */
1944 #if defined(ENABLE_JAVASE)
1945 name = javastring_toutf(t->name, false);
1946 #elif defined(ENABLE_JAVAME_CLDC1_1)
1951 utf_display_printable_ascii(name);
1954 if (thread->flags & THREAD_FLAG_DAEMON)
1957 #if SIZEOF_VOID_P == 8
1958 printf("prio=%d tid=0x%016lx\n", t->priority, (ptrint) thread->tid);
1960 printf("prio=%d tid=0x%08lx\n", t->priority, (ptrint) thread->tid);
1963 /* dump trace of thread */
1965 stacktrace_dump_trace(thread);
1968 thread = thread->next;
1969 } while ((thread != NULL) && (thread != mainthreadobj));
1973 /* threads_table_dump *********************************************************
1975 Dump the threads table for debugging purposes.
1978 file..............stream to write to
1980 ******************************************************************************/
1982 #if !defined(NDEBUG) && 0
1983 static void threads_table_dump(FILE *file)
1989 pthread_mutex_lock(&threadlistlock);
1991 size = threads_table.size;
1993 fprintf(file, "======== THREADS TABLE (size %d) ========\n", size);
1995 for (i=0; i<size; ++i) {
1996 index = threads_table.table[i].nextfree;
1998 fprintf(file, "%4d: ", i);
2001 fprintf(file, "free, nextfree = %d\n", (int) index);
2004 fprintf(file, "thread %p\n", (void*) threads_table.table[i].thread);
2008 fprintf(file, "======== END OF THREADS TABLE ========\n");
2010 pthread_mutex_unlock(&threadlistlock);
2015 * These are local overrides for various environment variables in Emacs.
2016 * Please do not remove this and leave it at the end of the file, where
2017 * Emacs will automagically detect them.
2018 * ---------------------------------------------------------------------
2021 * indent-tabs-mode: t
2025 * vim:noexpandtab:sw=4:ts=4: