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 7675 2007-04-05 14:23:04Z michi $
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 mutex for changing the thread list */
244 static pthread_mutex_t threadlistlock;
246 /* global mutex for stop-the-world */
247 static pthread_mutex_t stopworldlock;
249 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
251 static volatile int stopworldwhere;
253 /* semaphore used for acknowleding thread suspension */
254 static sem_t suspend_ack;
255 #if defined(__MIPS__)
256 static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
257 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
260 static pthread_attr_t threadattr;
262 /* mutexes used by the fake atomic instructions */
263 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
264 pthread_mutex_t _atomic_add_lock = PTHREAD_MUTEX_INITIALIZER;
265 pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
266 pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
270 /* threads_sem_init ************************************************************
272 Initialize a semaphore. Checks against errors and interruptions.
275 sem..............the semaphore to initialize
276 shared...........true if this semaphore will be shared between processes
277 value............the initial value for the semaphore
279 *******************************************************************************/
281 void threads_sem_init(sem_t *sem, bool shared, int value)
288 r = sem_init(sem, shared, value);
291 } while (errno == EINTR);
293 vm_abort("sem_init failed: %s", strerror(errno));
297 /* threads_sem_wait ************************************************************
299 Wait for a semaphore, non-interruptible.
301 IMPORTANT: Always use this function instead of `sem_wait` directly, as
302 `sem_wait` may be interrupted by signals!
305 sem..............the semaphore to wait on
307 *******************************************************************************/
309 void threads_sem_wait(sem_t *sem)
319 } while (errno == EINTR);
321 vm_abort("sem_wait failed: %s", strerror(errno));
325 /* threads_sem_post ************************************************************
327 Increase the count of a semaphore. Checks for errors.
330 sem..............the semaphore to increase the count of
332 *******************************************************************************/
334 void threads_sem_post(sem_t *sem)
340 /* unlike sem_wait, sem_post is not interruptible */
346 vm_abort("sem_post failed: %s", strerror(errno));
350 /* lock_stopworld **************************************************************
352 Enter the stopworld lock, specifying why the world shall be stopped.
355 where........ STOPWORLD_FROM_GC (1) from within GC
356 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
358 ******************************************************************************/
360 void lock_stopworld(int where)
362 pthread_mutex_lock(&stopworldlock);
363 stopworldwhere = where;
367 /* unlock_stopworld ************************************************************
369 Release the stopworld lock.
371 ******************************************************************************/
373 void unlock_stopworld(void)
376 pthread_mutex_unlock(&stopworldlock);
379 #if !defined(__DARWIN__)
380 /* Caller must hold threadlistlock */
381 static int threads_cast_sendsignals(int sig, int count)
384 threadobject *tobj = mainthreadobj;
385 threadobject *self = THREADOBJECT;
391 } while (tobj != mainthreadobj);
394 assert(tobj == mainthreadobj);
398 pthread_kill(tobj->tid, sig);
400 } while (tobj != mainthreadobj);
407 static void threads_cast_darwinstop(void)
409 threadobject *tobj = mainthreadobj;
410 threadobject *self = THREADOBJECT;
415 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
416 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
417 #if defined(__I386__)
418 i386_thread_state_t thread_state;
420 ppc_thread_state_t thread_state;
422 mach_port_t thread = tobj->mach_thread;
425 r = thread_suspend(thread);
427 if (r != KERN_SUCCESS)
428 vm_abort("thread_suspend failed");
430 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
431 &thread_state_count);
433 if (r != KERN_SUCCESS)
434 vm_abort("thread_get_state failed");
436 thread_restartcriticalsection((ucontext_t *) &thread_state);
438 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
441 if (r != KERN_SUCCESS)
442 vm_abort("thread_set_state failed");
446 } while (tobj != mainthreadobj);
449 static void threads_cast_darwinresume(void)
451 threadobject *tobj = mainthreadobj;
452 threadobject *self = THREADOBJECT;
457 mach_port_t thread = tobj->mach_thread;
460 r = thread_resume(thread);
462 if (r != KERN_SUCCESS)
463 vm_abort("thread_resume failed");
467 } while (tobj != mainthreadobj);
472 #if defined(__MIPS__)
473 static void threads_cast_irixresume(void)
475 pthread_mutex_lock(&suspend_ack_lock);
476 pthread_cond_broadcast(&suspend_cond);
477 pthread_mutex_unlock(&suspend_ack_lock);
481 #if !defined(DISABLE_GC)
483 void threads_cast_stopworld(void)
485 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
489 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
490 pthread_mutex_lock(&threadlistlock);
492 #if defined(__DARWIN__)
493 threads_cast_darwinstop();
494 #elif defined(__CYGWIN__)
498 count = threads_cast_sendsignals(GC_signum1(), 0);
499 for (i = 0; i < count; i++)
500 threads_sem_wait(&suspend_ack);
503 pthread_mutex_unlock(&threadlistlock);
506 void threads_cast_startworld(void)
508 pthread_mutex_lock(&threadlistlock);
509 #if defined(__DARWIN__)
510 threads_cast_darwinresume();
511 #elif defined(__MIPS__)
512 threads_cast_irixresume();
513 #elif defined(__CYGWIN__)
517 threads_cast_sendsignals(GC_signum2(), -1);
519 pthread_mutex_unlock(&threadlistlock);
524 #if !defined(__DARWIN__)
525 static void threads_sigsuspend_handler(ucontext_t *ctx)
530 /* XXX TWISTI: this is just a quick hack */
531 #if defined(ENABLE_JIT)
532 thread_restartcriticalsection(ctx);
535 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
536 (not POSIX async-safe). */
537 #if defined(__IRIX__)
538 pthread_mutex_lock(&suspend_ack_lock);
539 threads_sem_post(&suspend_ack);
540 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
541 pthread_mutex_unlock(&suspend_ack_lock);
542 #elif defined(__CYGWIN__)
546 threads_sem_post(&suspend_ack);
550 sigdelset(&sigs, sig);
555 /* This function is called from Boehm GC code. */
557 int cacao_suspendhandler(ucontext_t *ctx)
559 if (stopworldwhere != STOPWORLD_FROM_CLASS_NUMBERING)
562 threads_sigsuspend_handler(ctx);
567 #endif /* DISABLE_GC */
569 /* threads_set_current_threadobject ********************************************
571 Set the current thread object.
574 thread.......the thread object to set
576 *******************************************************************************/
578 static void threads_set_current_threadobject(threadobject *thread)
580 #if !defined(HAVE___THREAD)
581 pthread_setspecific(threads_current_threadobject_key, thread);
583 threads_current_threadobject = thread;
588 /* threads_init_threadobject **************************************************
590 Initialize implementation fields of a threadobject.
593 thread............the threadobject
595 ******************************************************************************/
597 static void threads_init_threadobject(threadobject *thread)
599 thread->tid = pthread_self();
603 /* TODO destroy all those things */
604 pthread_mutex_init(&(thread->joinmutex), NULL);
605 pthread_cond_init(&(thread->joincond), NULL);
607 pthread_mutex_init(&(thread->waitmutex), NULL);
608 pthread_cond_init(&(thread->waitcond), NULL);
610 thread->interrupted = false;
611 thread->signaled = false;
612 thread->sleeping = false;
616 /* threads_get_current_threadobject ********************************************
618 Return the threadobject of the current thread.
621 the current threadobject * (an instance of java.lang.Thread)
623 *******************************************************************************/
625 threadobject *threads_get_current_threadobject(void)
631 /* threads_preinit *************************************************************
633 Do some early initialization of stuff required.
635 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
636 is called AFTER this function!
638 *******************************************************************************/
640 void threads_preinit(void)
642 pthread_mutex_init(&threadlistlock, NULL);
643 pthread_mutex_init(&stopworldlock, NULL);
645 mainthreadobj = NEW(threadobject);
647 #if defined(ENABLE_STATISTICS)
649 size_threadobject += sizeof(threadobject);
652 mainthreadobj->object = NULL;
653 mainthreadobj->tid = pthread_self();
654 mainthreadobj->index = 1;
655 mainthreadobj->thinlock = lock_pre_compute_thinlock(mainthreadobj->index);
657 #if !defined(HAVE___THREAD)
658 pthread_key_create(&threads_current_threadobject_key, NULL);
660 threads_set_current_threadobject(mainthreadobj);
662 threads_sem_init(&suspend_ack, 0, 0);
664 /* initialize the threads table */
666 threads_table_init();
668 /* initialize subsystems */
676 /* threads_init ****************************************************************
678 Initializes the threads required by the JVM: main, finalizer.
680 *******************************************************************************/
682 bool threads_init(void)
684 java_lang_String *threadname;
685 threadobject *tempthread;
686 java_objectheader *o;
688 #if defined(ENABLE_JAVASE)
689 java_lang_ThreadGroup *threadgroup;
694 #if defined(WITH_CLASSPATH_GNU)
695 java_lang_VMThread *vmt;
698 tempthread = mainthreadobj;
700 /* XXX We have to find a new way to free lock records */
701 /* with the new locking algorithm. */
702 /* lock_record_free_pools(mainthreadobj->ee.lockrecordpools); */
705 /* This is kinda tricky, we grow the java.lang.Thread object so we
706 can keep the execution environment there. No Thread object must
707 have been created at an earlier time. */
709 class_java_lang_Thread->instancesize = sizeof(threadobject);
712 /* get methods we need in this file */
714 #if defined(WITH_CLASSPATH_GNU)
716 class_resolveclassmethod(class_java_lang_Thread,
718 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
719 class_java_lang_Thread,
723 class_resolveclassmethod(class_java_lang_Thread,
725 utf_new_char("(Ljava/lang/String;)V"),
726 class_java_lang_Thread,
730 if (method_thread_init == NULL)
733 /* create a vm internal thread object for the main thread */
734 /* XXX Michi: we do not need to do this here, we could use the one
735 created by threads_preinit() */
737 #if defined(ENABLE_GC_CACAO)
738 mainthreadobj = NEW(threadobject);
740 # if defined(ENABLE_STATISTICS)
742 size_threadobject += sizeof(threadobject);
745 mainthreadobj = GCNEW(threadobject);
748 if (mainthreadobj == NULL)
751 /* create a java.lang.Thread for the main thread */
753 mainthreadobj->object = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
755 if (mainthreadobj->object == NULL)
758 FREE(tempthread, threadobject);
760 threads_init_threadobject(mainthreadobj);
761 threads_set_current_threadobject(mainthreadobj);
762 lock_init_execution_env(mainthreadobj);
764 /* thread is running */
766 mainthreadobj->state = THREAD_STATE_RUNNABLE;
768 mainthreadobj->next = mainthreadobj;
769 mainthreadobj->prev = mainthreadobj;
771 threads_table_add(mainthreadobj);
773 /* mark main thread as Java thread */
775 mainthreadobj->flags = THREAD_FLAG_JAVA;
777 #if defined(ENABLE_INTRP)
778 /* create interpreter stack */
781 MSET(intrp_main_stack, 0, u1, opt_stacksize);
782 mainthreadobj->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
786 threadname = javastring_new(utf_new_char("main"));
788 #if defined(ENABLE_JAVASE)
789 /* allocate and init ThreadGroup */
791 threadgroup = (java_lang_ThreadGroup *)
792 native_new_and_init(class_java_lang_ThreadGroup);
794 if (threadgroup == NULL)
798 #if defined(WITH_CLASSPATH_GNU)
799 /* create a java.lang.VMThread for the main thread */
801 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
808 vmt->thread = mainthreadobj->object;
809 vmt->vmdata = (java_lang_Object *) mainthreadobj;
811 /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
812 o = (java_objectheader *) mainthreadobj->object;
814 (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
816 #elif defined(WITH_CLASSPATH_CLDC1_1)
819 mainthreadobj->object->vm_thread = (java_lang_Object *) mainthreadobj;
821 /* call public Thread(String name) */
823 o = (java_objectheader *) mainthreadobj->object;
825 (void) vm_call_method(method_thread_init, o, threadname);
831 #if defined(ENABLE_JAVASE)
832 mainthreadobj->object->group = threadgroup;
834 /* add main thread to java.lang.ThreadGroup */
836 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
838 utf_java_lang_Thread__V,
839 class_java_lang_ThreadGroup,
842 o = (java_objectheader *) threadgroup;
843 t = mainthreadobj->object;
845 (void) vm_call_method(m, o, t);
852 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
854 /* initialize the thread attribute object */
856 if (pthread_attr_init(&threadattr)) {
857 log_println("pthread_attr_init failed: %s", strerror(errno));
861 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
863 /* everything's ok */
869 /* threads_table_init *********************************************************
871 Initialize the global threads table.
873 ******************************************************************************/
875 static void threads_table_init(void)
880 size = THREADS_INITIAL_TABLE_SIZE;
882 threads_table.size = size;
883 threads_table.table = MNEW(threads_table_entry_t, size);
885 /* link the entries in a freelist */
887 for (i=0; i<size; ++i) {
888 threads_table.table[i].nextfree = i+1;
891 /* terminate the freelist */
893 threads_table.table[size-1].nextfree = 0; /* index 0 is never free */
897 /* threads_table_add **********************************************************
899 Add a thread to the global threads table. The index is entered in the
900 threadobject. The thinlock value for the thread is pre-computed.
903 thread............the thread to add
906 The table index for the newly added thread. This value has also been
907 entered in the threadobject.
910 The caller must hold the threadlistlock!
912 ******************************************************************************/
914 static s4 threads_table_add(threadobject *thread)
921 /* table[0] serves as the head of the freelist */
923 index = threads_table.table[0].nextfree;
925 /* if we got a free index, use it */
929 threads_table.table[0].nextfree = threads_table.table[index].nextfree;
930 threads_table.table[index].thread = thread;
931 thread->index = index;
932 thread->thinlock = lock_pre_compute_thinlock(index);
936 /* we must grow the table */
938 oldsize = threads_table.size;
939 newsize = oldsize * 2;
941 threads_table.table = MREALLOC(threads_table.table, threads_table_entry_t,
943 threads_table.size = newsize;
945 /* link the new entries to a free list */
947 for (i=oldsize; i<newsize; ++i) {
948 threads_table.table[i].nextfree = i+1;
951 /* terminate the freelist */
953 threads_table.table[newsize-1].nextfree = 0; /* index 0 is never free */
955 /* use the first of the new entries */
962 /* threads_table_remove *******************************************************
964 Remove a thread from the global threads table.
967 thread............the thread to remove
970 The caller must hold the threadlistlock!
972 ******************************************************************************/
974 static void threads_table_remove(threadobject *thread)
978 index = thread->index;
980 /* put the index into the freelist */
982 threads_table.table[index] = threads_table.table[0];
983 threads_table.table[0].nextfree = index;
985 /* delete the index in the threadobject to discover bugs */
992 /* threads_startup_thread ******************************************************
994 Thread startup function called by pthread_create.
996 Thread which have a startup.function != NULL are marked as internal
997 threads. All other threads are threated as normal Java threads.
999 NOTE: This function is not called directly by pthread_create. The Boehm GC
1000 inserts its own GC_start_routine in between, which then calls
1004 t............the argument passed to pthread_create, ie. a pointer to
1005 a startupinfo struct. CAUTION: When the `psem` semaphore
1006 is posted, the startupinfo struct becomes invalid! (It
1007 is allocated on the stack of threads_start_thread.)
1009 ******************************************************************************/
1011 static void *threads_startup_thread(void *t)
1013 startupinfo *startup;
1014 threadobject *thread;
1015 #if defined(WITH_CLASSPATH_GNU)
1016 java_lang_VMThread *vmt;
1019 threadobject *tnext;
1022 java_objectheader *o;
1023 functionptr function;
1025 #if defined(ENABLE_INTRP)
1026 u1 *intrp_thread_stack;
1028 /* create interpreter stack */
1031 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
1032 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
1035 intrp_thread_stack = NULL;
1038 /* get passed startupinfo structure and the values in there */
1041 t = NULL; /* make sure it's not used wrongly */
1043 thread = startup->thread;
1044 function = startup->function;
1045 psem = startup->psem;
1047 /* Seems like we've encountered a situation where thread->tid was not set by
1048 * pthread_create. We alleviate this problem by waiting for pthread_create
1050 threads_sem_wait(startup->psem_first);
1052 /* set the thread object */
1054 #if defined(__DARWIN__)
1055 thread->mach_thread = mach_thread_self();
1057 threads_set_current_threadobject(thread);
1059 /* thread is running */
1061 thread->state = THREAD_STATE_RUNNABLE;
1063 /* insert the thread into the threadlist and the threads table */
1065 pthread_mutex_lock(&threadlistlock);
1067 thread->prev = mainthreadobj;
1068 thread->next = tnext = mainthreadobj->next;
1069 mainthreadobj->next = thread;
1070 tnext->prev = thread;
1072 threads_table_add(thread);
1074 pthread_mutex_unlock(&threadlistlock);
1076 /* init data structures of this thread */
1078 lock_init_execution_env(thread);
1080 /* tell threads_startup_thread that we registered ourselves */
1081 /* CAUTION: *startup becomes invalid with this! */
1084 threads_sem_post(psem);
1086 /* set our priority */
1088 threads_set_thread_priority(thread->tid, thread->object->priority);
1090 #if defined(ENABLE_INTRP)
1091 /* set interpreter stack */
1094 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1097 #if defined(ENABLE_JVMTI)
1098 /* fire thread start event */
1101 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1104 /* find and run the Thread.run()V method if no other function was passed */
1106 if (function == NULL) {
1107 /* this is a normal Java thread */
1109 thread->flags |= THREAD_FLAG_JAVA;
1111 #if defined(WITH_CLASSPATH_GNU)
1112 /* We need to start the run method of
1113 java.lang.VMThread. Since this is a final class, we can use
1114 the class object directly. */
1116 c = class_java_lang_VMThread;
1117 #elif defined(WITH_CLASSPATH_CLDC1_1)
1118 c = thread->object->header.vftbl->class;
1121 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1124 vm_abort("threads_startup_thread: run() method not found in class");
1126 /* set ThreadMXBean variables */
1128 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1129 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1131 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1132 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1133 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1134 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1136 #if defined(WITH_CLASSPATH_GNU)
1137 /* we need to start the run method of java.lang.VMThread */
1139 vmt = (java_lang_VMThread *) thread->object->vmThread;
1140 o = (java_objectheader *) vmt;
1142 #elif defined(WITH_CLASSPATH_CLDC1_1)
1143 o = (java_objectheader *) thread->object;
1146 /* run the thread */
1148 (void) vm_call_method(m, o);
1151 /* this is an internal thread */
1153 thread->flags |= THREAD_FLAG_INTERNAL;
1155 /* set ThreadMXBean variables */
1157 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1158 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1160 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1161 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1162 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1163 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1165 /* call passed function, e.g. finalizer_thread */
1170 #if defined(ENABLE_JVMTI)
1171 /* fire thread end event */
1174 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1177 threads_detach_thread(thread);
1179 /* set ThreadMXBean variables */
1181 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1187 /* threads_start_javathread ***************************************************
1189 Start a thread in the JVM. Only the java thread object exists so far.
1192 object.....the java thread object java.lang.Thread
1194 ******************************************************************************/
1196 void threads_start_javathread(java_lang_Thread *object)
1198 threadobject *thread;
1200 /* create the vm internal threadobject */
1202 thread = NEW(threadobject);
1204 #if defined(ENABLE_STATISTICS)
1206 size_threadobject += sizeof(threadobject);
1209 /* link the two objects together */
1211 thread->object = object;
1213 #if defined(WITH_CLASSPATH_GNU)
1214 assert(object->vmThread);
1215 assert(object->vmThread->vmdata == NULL);
1216 object->vmThread->vmdata = (java_lang_Object *) thread;
1217 #elif defined(WITH_CLASSPATH_CLDC1_1)
1218 object->vm_thread = (java_lang_Object *) thread;
1221 /* actually start the thread */
1222 /* don't pass a function pointer (NULL) since we want Thread.run()V here */
1224 threads_start_thread(thread, NULL);
1228 /* threads_start_thread ********************************************************
1230 Start a thread in the JVM. Both (vm internal and java) thread objects exist.
1233 thread.......the thread object
1234 function.....function to run in the new thread. NULL means that the
1235 "run" method of the object `t` should be called
1237 ******************************************************************************/
1239 void threads_start_thread(threadobject *thread, functionptr function)
1243 pthread_attr_t attr;
1244 startupinfo startup;
1246 /* fill startupinfo structure passed by pthread_create to
1247 * threads_startup_thread */
1249 startup.thread = thread;
1250 startup.function = function; /* maybe we don't call Thread.run()V */
1251 startup.psem = &sem;
1252 startup.psem_first = &sem_first;
1254 threads_sem_init(&sem, 0, 0);
1255 threads_sem_init(&sem_first, 0, 0);
1257 /* initialize thread attribute object */
1259 if (pthread_attr_init(&attr))
1260 vm_abort("pthread_attr_init failed: %s", strerror(errno));
1262 /* initialize thread stacksize */
1264 if (pthread_attr_setstacksize(&attr, opt_stacksize))
1265 vm_abort("pthread_attr_setstacksize failed: %s", strerror(errno));
1267 /* create the thread */
1269 if (pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup))
1270 vm_abort("pthread_create failed: %s", strerror(errno));
1272 /* signal that pthread_create has returned, so thread->tid is valid */
1274 threads_sem_post(&sem_first);
1276 /* wait here until the thread has entered itself into the thread list */
1278 threads_sem_wait(&sem);
1283 sem_destroy(&sem_first);
1287 /* threads_set_thread_priority *************************************************
1289 Set the priority of the given thread.
1292 tid..........thread id
1293 priority.....priority to set
1295 ******************************************************************************/
1297 void threads_set_thread_priority(pthread_t tid, int priority)
1299 struct sched_param schedp;
1302 pthread_getschedparam(tid, &policy, &schedp);
1303 schedp.sched_priority = priority;
1304 pthread_setschedparam(tid, policy, &schedp);
1308 /* threads_attach_current_thread ***********************************************
1310 Attaches the current thread to the VM. Used in JNI.
1312 *******************************************************************************/
1314 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
1316 threadobject *thread;
1318 java_lang_String *s;
1319 java_objectheader *o;
1320 java_lang_Thread *t;
1322 #if defined(ENABLE_JAVASE)
1323 java_lang_ThreadGroup *group;
1327 #if defined(WITH_CLASSPATH_GNU)
1328 java_lang_VMThread *vmt;
1331 /* create a vm internal thread object */
1333 thread = NEW(threadobject);
1335 #if defined(ENABLE_STATISTICS)
1337 size_threadobject += sizeof(threadobject);
1343 /* create a java.lang.Thread object */
1345 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
1352 threads_init_threadobject(thread);
1353 threads_set_current_threadobject(thread);
1354 lock_init_execution_env(thread);
1356 /* thread is running */
1358 thread->state = THREAD_STATE_RUNNABLE;
1360 /* insert the thread into the threadlist and the threads table */
1362 pthread_mutex_lock(&threadlistlock);
1364 thread->prev = mainthreadobj;
1365 thread->next = mainthreadobj->next;
1366 mainthreadobj->next = thread;
1367 thread->next->prev = thread;
1369 threads_table_add(thread);
1371 pthread_mutex_unlock(&threadlistlock);
1373 /* mark thread as Java thread */
1375 thread->flags = THREAD_FLAG_JAVA;
1378 thread->flags |= THREAD_FLAG_DAEMON;
1380 #if defined(ENABLE_INTRP)
1381 /* create interpreter stack */
1384 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1385 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
1389 #if defined(WITH_CLASSPATH_GNU)
1390 /* create a java.lang.VMThread object */
1392 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
1397 /* set the thread */
1400 vmt->vmdata = (java_lang_Object *) thread;
1401 #elif defined(WITH_CLASSPATH_CLDC1_1)
1402 t->vm_thread = (java_lang_Object *) thread;
1405 if (vm_aargs != NULL) {
1406 u = utf_new_char(vm_aargs->name);
1407 #if defined(ENABLE_JAVASE)
1408 group = (java_lang_ThreadGroup *) vm_aargs->group;
1413 #if defined(ENABLE_JAVASE)
1414 group = mainthreadobj->object->group;
1418 s = javastring_new(u);
1420 o = (java_objectheader *) thread->object;
1422 #if defined(WITH_CLASSPATH_GNU)
1423 (void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
1425 #elif defined(WITH_CLASSPATH_CLDC1_1)
1426 (void) vm_call_method(method_thread_init, o, s);
1432 #if defined(ENABLE_JAVASE)
1433 /* store the thread group in the object */
1435 thread->object->group = group;
1437 /* add thread to given thread-group */
1439 m = class_resolveclassmethod(group->header.vftbl->class,
1441 utf_java_lang_Thread__V,
1442 class_java_lang_ThreadGroup,
1445 o = (java_objectheader *) group;
1447 (void) vm_call_method(m, o, t);
1457 /* threads_detach_thread *******************************************************
1459 Detaches the passed thread from the VM. Used in JNI.
1461 *******************************************************************************/
1463 bool threads_detach_thread(threadobject *thread)
1465 #if defined(ENABLE_JAVASE)
1466 java_lang_ThreadGroup *group;
1468 java_objectheader *o;
1469 java_lang_Thread *t;
1472 /* Allow lock record pools to be used by other threads. They
1473 cannot be deleted so we'd better not waste them. */
1475 /* XXX We have to find a new way to free lock records */
1476 /* with the new locking algorithm. */
1477 /* lock_record_free_pools(thread->ee.lockrecordpools); */
1479 /* XXX implement uncaught exception stuff (like JamVM does) */
1481 #if defined(ENABLE_JAVASE)
1482 /* remove thread from the thread group */
1484 group = thread->object->group;
1486 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1488 if (group != NULL) {
1489 m = class_resolveclassmethod(group->header.vftbl->class,
1491 utf_java_lang_Thread__V,
1492 class_java_lang_ThreadGroup,
1498 o = (java_objectheader *) group;
1501 (void) vm_call_method(m, o, t);
1508 /* thread is terminated */
1510 thread->state = THREAD_STATE_TERMINATED;
1512 /* remove thread from thread list and threads table, do this
1515 pthread_mutex_lock(&threadlistlock);
1517 thread->next->prev = thread->prev;
1518 thread->prev->next = thread->next;
1520 threads_table_remove(thread);
1522 pthread_mutex_unlock(&threadlistlock);
1524 /* reset thread id (lock on joinmutex? TWISTI) */
1526 pthread_mutex_lock(&(thread->joinmutex));
1528 pthread_mutex_unlock(&(thread->joinmutex));
1530 /* tell everyone that a thread has finished */
1532 pthread_cond_broadcast(&(thread->joincond));
1534 /* free the vm internal thread object */
1536 FREE(thread, threadobject);
1538 #if defined(ENABLE_STATISTICS)
1540 size_threadobject -= sizeof(threadobject);
1547 /* threads_find_non_daemon_thread **********************************************
1549 Helper function used by threads_join_all_threads for finding
1550 non-daemon threads that are still running.
1552 *******************************************************************************/
1554 /* At the end of the program, we wait for all running non-daemon
1557 static threadobject *threads_find_non_daemon_thread(threadobject *thread)
1559 while (thread != mainthreadobj) {
1560 if (!(thread->flags & THREAD_FLAG_DAEMON))
1563 thread = thread->prev;
1570 /* threads_join_all_threads ****************************************************
1572 Join all non-daemon threads.
1574 *******************************************************************************/
1576 void threads_join_all_threads(void)
1578 threadobject *thread;
1580 pthread_mutex_lock(&threadlistlock);
1582 while ((thread = threads_find_non_daemon_thread(mainthreadobj->prev)) != NULL) {
1583 pthread_mutex_lock(&(thread->joinmutex));
1585 pthread_mutex_unlock(&threadlistlock);
1588 pthread_cond_wait(&(thread->joincond), &(thread->joinmutex));
1590 pthread_mutex_unlock(&(thread->joinmutex));
1592 pthread_mutex_lock(&threadlistlock);
1595 pthread_mutex_unlock(&threadlistlock);
1599 /* threads_timespec_earlier ****************************************************
1601 Return true if timespec tv1 is earlier than timespec tv2.
1604 tv1..........first timespec
1605 tv2..........second timespec
1608 true, if the first timespec is earlier
1610 *******************************************************************************/
1612 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1613 const struct timespec *tv2)
1615 return (tv1->tv_sec < tv2->tv_sec)
1617 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1621 /* threads_current_time_is_earlier_than ****************************************
1623 Check if the current time is earlier than the given timespec.
1626 tv...........the timespec to compare against
1629 true, if the current time is earlier
1631 *******************************************************************************/
1633 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1635 struct timeval tvnow;
1636 struct timespec tsnow;
1638 /* get current time */
1640 if (gettimeofday(&tvnow, NULL) != 0)
1641 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1643 /* convert it to a timespec */
1645 tsnow.tv_sec = tvnow.tv_sec;
1646 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1648 /* compare current time with the given timespec */
1650 return threads_timespec_earlier(&tsnow, tv);
1654 /* threads_wait_with_timeout ***************************************************
1656 Wait until the given point in time on a monitor until either
1657 we are notified, we are interrupted, or the time is up.
1660 t............the current thread
1661 wakeupTime...absolute (latest) wakeup time
1662 If both tv_sec and tv_nsec are zero, this function
1663 waits for an unlimited amount of time.
1666 true.........if the wait has been interrupted,
1667 false........if the wait was ended by notification or timeout
1669 *******************************************************************************/
1671 static bool threads_wait_with_timeout(threadobject *thread,
1672 struct timespec *wakeupTime)
1674 bool wasinterrupted;
1676 /* acquire the waitmutex */
1678 pthread_mutex_lock(&thread->waitmutex);
1680 /* mark us as sleeping */
1682 thread->sleeping = true;
1684 /* wait on waitcond */
1686 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1688 while (!thread->interrupted && !thread->signaled
1689 && threads_current_time_is_earlier_than(wakeupTime))
1691 thread->state = THREAD_STATE_TIMED_WAITING;
1693 pthread_cond_timedwait(&thread->waitcond, &thread->waitmutex,
1696 thread->state = THREAD_STATE_RUNNABLE;
1701 while (!thread->interrupted && !thread->signaled) {
1702 thread->state = THREAD_STATE_WAITING;
1704 pthread_cond_wait(&thread->waitcond, &thread->waitmutex);
1706 thread->state = THREAD_STATE_RUNNABLE;
1710 /* check if we were interrupted */
1712 wasinterrupted = thread->interrupted;
1714 /* reset all flags */
1716 thread->interrupted = false;
1717 thread->signaled = false;
1718 thread->sleeping = false;
1720 /* release the waitmutex */
1722 pthread_mutex_unlock(&thread->waitmutex);
1724 return wasinterrupted;
1728 /* threads_wait_with_timeout_relative ******************************************
1730 Wait for the given maximum amount of time on a monitor until either
1731 we are notified, we are interrupted, or the time is up.
1734 t............the current thread
1735 millis.......milliseconds to wait
1736 nanos........nanoseconds to wait
1739 true.........if the wait has been interrupted,
1740 false........if the wait was ended by notification or timeout
1742 *******************************************************************************/
1744 bool threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1747 struct timespec wakeupTime;
1749 /* calculate the the (latest) wakeup time */
1751 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1755 return threads_wait_with_timeout(thread, &wakeupTime);
1759 /* threads_calc_absolute_time **************************************************
1761 Calculate the absolute point in time a given number of ms and ns from now.
1764 millis............milliseconds from now
1765 nanos.............nanoseconds from now
1768 *tm...............receives the timespec of the absolute point in time
1770 *******************************************************************************/
1772 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1774 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1777 gettimeofday(&tv, NULL);
1778 tv.tv_sec += millis / 1000;
1780 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1781 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1782 tm->tv_nsec = nsec % 1000000000;
1791 /* threads_thread_interrupt ****************************************************
1793 Interrupt the given thread.
1795 The thread gets the "waitcond" signal and
1796 its interrupted flag is set to true.
1799 thread............the thread to interrupt
1801 *******************************************************************************/
1803 void threads_thread_interrupt(threadobject *thread)
1805 /* Signal the thread a "waitcond" and tell it that it has been
1808 pthread_mutex_lock(&thread->waitmutex);
1810 /* Interrupt blocking system call using a signal. */
1812 pthread_kill(thread->tid, SIGHUP);
1814 if (thread->sleeping)
1815 pthread_cond_signal(&thread->waitcond);
1817 thread->interrupted = true;
1819 pthread_mutex_unlock(&thread->waitmutex);
1823 /* threads_check_if_interrupted_and_reset **************************************
1825 Check if the current thread has been interrupted and reset the
1829 true, if the current thread had been interrupted
1831 *******************************************************************************/
1833 bool threads_check_if_interrupted_and_reset(void)
1835 threadobject *thread;
1838 thread = THREADOBJECT;
1840 /* get interrupted flag */
1842 intr = thread->interrupted;
1844 /* reset interrupted flag */
1846 thread->interrupted = false;
1852 /* threads_thread_has_been_interrupted *****************************************
1854 Check if the given thread has been interrupted
1857 t............the thread to check
1860 true, if the given thread had been interrupted
1862 *******************************************************************************/
1864 bool threads_thread_has_been_interrupted(threadobject *thread)
1866 return thread->interrupted;
1870 /* threads_sleep ***************************************************************
1872 Sleep the current thread for the specified amount of time.
1874 *******************************************************************************/
1876 void threads_sleep(s8 millis, s4 nanos)
1878 threadobject *thread;
1879 struct timespec wakeupTime;
1880 bool wasinterrupted;
1882 thread = THREADOBJECT;
1884 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1886 wasinterrupted = threads_wait_with_timeout(thread, &wakeupTime);
1889 exceptions_throw_interruptedexception();
1893 /* threads_yield ***************************************************************
1895 Yield to the scheduler.
1897 *******************************************************************************/
1899 void threads_yield(void)
1905 /* threads_table_dump *********************************************************
1907 Dump the threads table for debugging purposes.
1910 file..............stream to write to
1912 ******************************************************************************/
1914 #if !defined(NDEBUG) && 0
1915 static void threads_table_dump(FILE *file)
1921 pthread_mutex_lock(&threadlistlock);
1923 size = threads_table.size;
1925 fprintf(file, "======== THREADS TABLE (size %d) ========\n", size);
1927 for (i=0; i<size; ++i) {
1928 index = threads_table.table[i].nextfree;
1930 fprintf(file, "%4d: ", i);
1933 fprintf(file, "free, nextfree = %d\n", (int) index);
1936 fprintf(file, "thread %p\n", (void*) threads_table.table[i].thread);
1940 fprintf(file, "======== END OF THREADS TABLE ========\n");
1942 pthread_mutex_unlock(&threadlistlock);
1947 * These are local overrides for various environment variables in Emacs.
1948 * Please do not remove this and leave it at the end of the file, where
1949 * Emacs will automagically detect them.
1950 * ---------------------------------------------------------------------
1953 * indent-tabs-mode: t
1957 * vim:noexpandtab:sw=4:ts=4: