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 7667 2007-04-05 00:16:05Z 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 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 void threads_cast_darwinstop(void)
410 threadobject *tobj = mainthreadobj;
411 threadobject *self = THREADOBJECT;
416 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
417 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
418 #if defined(__I386__)
419 i386_thread_state_t thread_state;
421 ppc_thread_state_t thread_state;
423 mach_port_t thread = tobj->mach_thread;
426 r = thread_suspend(thread);
428 if (r != KERN_SUCCESS)
429 vm_abort("thread_suspend failed");
431 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
432 &thread_state_count);
434 if (r != KERN_SUCCESS)
435 vm_abort("thread_get_state failed");
437 thread_restartcriticalsection((ucontext_t *) &thread_state);
439 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
442 if (r != KERN_SUCCESS)
443 vm_abort("thread_set_state failed");
447 } while (tobj != mainthreadobj);
450 static void threads_cast_darwinresume(void)
452 threadobject *tobj = mainthreadobj;
453 threadobject *self = THREADOBJECT;
458 mach_port_t thread = tobj->mach_thread;
461 r = thread_resume(thread);
463 if (r != KERN_SUCCESS)
464 vm_abort("thread_resume failed");
468 } while (tobj != mainthreadobj);
473 #if defined(__MIPS__)
474 static void threads_cast_irixresume(void)
476 pthread_mutex_lock(&suspend_ack_lock);
477 pthread_cond_broadcast(&suspend_cond);
478 pthread_mutex_unlock(&suspend_ack_lock);
483 #if !defined(__DARWIN__)
484 static void threads_sigsuspend_handler(ucontext_t *ctx)
489 /* XXX TWISTI: this is just a quick hack */
490 #if defined(ENABLE_JIT)
491 thread_restartcriticalsection(ctx);
494 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
495 (not POSIX async-safe). */
496 #if defined(__IRIX__)
497 pthread_mutex_lock(&suspend_ack_lock);
498 threads_sem_post(&suspend_ack);
499 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
500 pthread_mutex_unlock(&suspend_ack_lock);
501 #elif defined(__CYGWIN__)
505 threads_sem_post(&suspend_ack);
509 sigdelset(&sigs, sig);
517 /* threads_stopworld ***********************************************************
519 Stops the world from turning. All threads except the calling one
520 are suspended. The function returns as soon as all threads have
521 acknowledged their suspension.
523 *******************************************************************************/
525 #if !defined(DISABLE_GC)
526 void threads_stopworld(void)
528 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
529 threadobject *tobj = mainthreadobj;
530 threadobject *self = THREADOBJECT;
535 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
536 pthread_mutex_lock(&threadlistlock);
538 #if defined(__DARWIN__)
539 threads_cast_darwinstop();
540 #elif defined(__CYGWIN__)
544 /* count how many threads we suspended */
547 /* suspend all running threads */
550 result = threads_suspend_thread(tobj, SUSPEND_REASON_STOPWORLD);
555 } while (tobj != mainthreadobj);
557 /* wait till all threads are suspended */
558 for (i = 0; i < count; i++)
559 threads_sem_wait(&suspend_ack);
562 pthread_mutex_unlock(&threadlistlock);
564 #endif /* !defined(DISABLE_GC) */
567 /* threads_startworld **********************************************************
569 Starts the world again after it has previously been stopped.
571 *******************************************************************************/
573 #if !defined(DISABLE_GC)
574 void threads_startworld(void)
576 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
577 threadobject *tobj = mainthreadobj;
578 threadobject *self = THREADOBJECT;
582 pthread_mutex_lock(&threadlistlock);
584 #if defined(__DARWIN__)
585 threads_cast_darwinresume();
586 #elif defined(__MIPS__)
587 threads_cast_irixresume();
588 #elif defined(__CYGWIN__)
592 /* resume all thread we haltet */
595 result = threads_resume_thread(tobj);
599 } while (tobj != mainthreadobj);
602 pthread_mutex_unlock(&threadlistlock);
605 #endif /* DISABLE_GC */
608 /* threads_set_current_threadobject ********************************************
610 Set the current thread object.
613 thread.......the thread object to set
615 *******************************************************************************/
617 static void threads_set_current_threadobject(threadobject *thread)
619 #if !defined(HAVE___THREAD)
620 pthread_setspecific(threads_current_threadobject_key, thread);
622 threads_current_threadobject = thread;
627 /* threads_init_threadobject **************************************************
629 Initialize implementation fields of a threadobject.
632 thread............the threadobject
634 ******************************************************************************/
636 static void threads_init_threadobject(threadobject *thread)
638 thread->tid = pthread_self();
642 #if defined(ENABLE_GC_CACAO)
643 thread->flags |= THREAD_FLAG_IN_NATIVE;
644 thread->gc_critical = false;
647 /* TODO destroy all those things */
648 pthread_mutex_init(&(thread->joinmutex), NULL);
649 pthread_cond_init(&(thread->joincond), NULL);
651 pthread_mutex_init(&(thread->waitmutex), NULL);
652 pthread_cond_init(&(thread->waitcond), NULL);
654 thread->interrupted = false;
655 thread->signaled = false;
656 thread->sleeping = false;
660 /* threads_get_current_threadobject ********************************************
662 Return the threadobject of the current thread.
665 the current threadobject *
667 *******************************************************************************/
669 threadobject *threads_get_current_threadobject(void)
675 /* threads_preinit *************************************************************
677 Do some early initialization of stuff required.
679 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
680 is called AFTER this function!
682 *******************************************************************************/
684 void threads_preinit(void)
686 pthread_mutexattr_t mutexattr;
687 pthread_mutexattr_init(&mutexattr);
688 pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
689 pthread_mutex_init(&compiler_mutex, &mutexattr);
690 pthread_mutexattr_destroy(&mutexattr);
692 pthread_mutex_init(&threadlistlock, NULL);
693 pthread_mutex_init(&stopworldlock, NULL);
695 mainthreadobj = NEW(threadobject);
697 #if defined(ENABLE_STATISTICS)
699 size_threadobject += sizeof(threadobject);
702 mainthreadobj->object = NULL;
703 mainthreadobj->tid = pthread_self();
704 mainthreadobj->index = 1;
705 mainthreadobj->thinlock = lock_pre_compute_thinlock(mainthreadobj->index);
707 #if !defined(HAVE___THREAD)
708 pthread_key_create(&threads_current_threadobject_key, NULL);
710 threads_set_current_threadobject(mainthreadobj);
712 threads_sem_init(&suspend_ack, 0, 0);
714 /* initialize the threads table */
716 threads_table_init();
718 /* initialize subsystems */
726 /* threads_init ****************************************************************
728 Initializes the threads required by the JVM: main, finalizer.
730 *******************************************************************************/
732 bool threads_init(void)
734 java_lang_String *threadname;
735 threadobject *tempthread;
736 java_objectheader *o;
738 #if defined(ENABLE_JAVASE)
739 java_lang_ThreadGroup *threadgroup;
744 #if defined(WITH_CLASSPATH_GNU)
745 java_lang_VMThread *vmt;
748 tempthread = mainthreadobj;
750 /* XXX We have to find a new way to free lock records */
751 /* with the new locking algorithm. */
752 /* lock_record_free_pools(mainthreadobj->ee.lockrecordpools); */
755 /* This is kinda tricky, we grow the java.lang.Thread object so we
756 can keep the execution environment there. No Thread object must
757 have been created at an earlier time. */
759 class_java_lang_Thread->instancesize = sizeof(threadobject);
762 /* get methods we need in this file */
764 #if defined(WITH_CLASSPATH_GNU)
766 class_resolveclassmethod(class_java_lang_Thread,
768 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
769 class_java_lang_Thread,
773 class_resolveclassmethod(class_java_lang_Thread,
775 utf_new_char("(Ljava/lang/String;)V"),
776 class_java_lang_Thread,
780 if (method_thread_init == NULL)
783 /* create a vm internal thread object for the main thread */
784 /* XXX Michi: we do not need to do this here, we could use the one
785 created by threads_preinit() */
787 #if defined(ENABLE_GC_CACAO)
788 mainthreadobj = NEW(threadobject);
790 # if defined(ENABLE_STATISTICS)
792 size_threadobject += sizeof(threadobject);
795 mainthreadobj = GCNEW(threadobject);
798 if (mainthreadobj == NULL)
801 /* create a java.lang.Thread for the main thread */
803 mainthreadobj->object = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
805 if (mainthreadobj->object == NULL)
808 FREE(tempthread, threadobject);
810 threads_init_threadobject(mainthreadobj);
811 threads_set_current_threadobject(mainthreadobj);
812 lock_init_execution_env(mainthreadobj);
814 mainthreadobj->next = mainthreadobj;
815 mainthreadobj->prev = mainthreadobj;
817 threads_table_add(mainthreadobj);
819 /* mark main thread as Java thread */
821 mainthreadobj->flags = THREAD_FLAG_JAVA;
823 #if defined(ENABLE_INTRP)
824 /* create interpreter stack */
827 MSET(intrp_main_stack, 0, u1, opt_stacksize);
828 mainthreadobj->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
832 threadname = javastring_new(utf_new_char("main"));
834 #if defined(ENABLE_JAVASE)
835 /* allocate and init ThreadGroup */
837 threadgroup = (java_lang_ThreadGroup *)
838 native_new_and_init(class_java_lang_ThreadGroup);
840 if (threadgroup == NULL)
844 #if defined(WITH_CLASSPATH_GNU)
845 /* create a java.lang.VMThread for the main thread */
847 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
854 vmt->thread = mainthreadobj->object;
855 vmt->vmdata = (java_lang_Object *) mainthreadobj;
857 /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
858 o = (java_objectheader *) mainthreadobj->object;
860 (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
862 #elif defined(WITH_CLASSPATH_CLDC1_1)
865 mainthreadobj->object->vm_thread = (java_lang_Object *) mainthreadobj;
867 /* call public Thread(String name) */
869 o = (java_objectheader *) mainthreadobj->object;
871 (void) vm_call_method(method_thread_init, o, threadname);
877 #if defined(ENABLE_JAVASE)
878 mainthreadobj->object->group = threadgroup;
880 /* add main thread to java.lang.ThreadGroup */
882 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
884 utf_java_lang_Thread__V,
885 class_java_lang_ThreadGroup,
888 o = (java_objectheader *) threadgroup;
889 t = mainthreadobj->object;
891 (void) vm_call_method(m, o, t);
898 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
900 /* initialize the thread attribute object */
902 if (pthread_attr_init(&threadattr)) {
903 log_println("pthread_attr_init failed: %s", strerror(errno));
907 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
909 /* everything's ok */
915 /* threads_table_init *********************************************************
917 Initialize the global threads table.
919 ******************************************************************************/
921 static void threads_table_init(void)
926 size = THREADS_INITIAL_TABLE_SIZE;
928 threads_table.size = size;
929 threads_table.table = MNEW(threads_table_entry_t, size);
931 /* link the entries in a freelist */
933 for (i=0; i<size; ++i) {
934 threads_table.table[i].nextfree = i+1;
937 /* terminate the freelist */
939 threads_table.table[size-1].nextfree = 0; /* index 0 is never free */
943 /* threads_table_add **********************************************************
945 Add a thread to the global threads table. The index is entered in the
946 threadobject. The thinlock value for the thread is pre-computed.
949 thread............the thread to add
952 The table index for the newly added thread. This value has also been
953 entered in the threadobject.
956 The caller must hold the threadlistlock!
958 ******************************************************************************/
960 static s4 threads_table_add(threadobject *thread)
967 /* table[0] serves as the head of the freelist */
969 index = threads_table.table[0].nextfree;
971 /* if we got a free index, use it */
975 threads_table.table[0].nextfree = threads_table.table[index].nextfree;
976 threads_table.table[index].thread = thread;
977 thread->index = index;
978 thread->thinlock = lock_pre_compute_thinlock(index);
982 /* we must grow the table */
984 oldsize = threads_table.size;
985 newsize = oldsize * 2;
987 threads_table.table = MREALLOC(threads_table.table, threads_table_entry_t,
989 threads_table.size = newsize;
991 /* link the new entries to a free list */
993 for (i=oldsize; i<newsize; ++i) {
994 threads_table.table[i].nextfree = i+1;
997 /* terminate the freelist */
999 threads_table.table[newsize-1].nextfree = 0; /* index 0 is never free */
1001 /* use the first of the new entries */
1008 /* threads_table_remove *******************************************************
1010 Remove a thread from the global threads table.
1013 thread............the thread to remove
1016 The caller must hold the threadlistlock!
1018 ******************************************************************************/
1020 static void threads_table_remove(threadobject *thread)
1024 index = thread->index;
1026 /* put the index into the freelist */
1028 threads_table.table[index] = threads_table.table[0];
1029 threads_table.table[0].nextfree = index;
1031 /* delete the index in the threadobject to discover bugs */
1032 #if !defined(NDEBUG)
1038 /* threads_startup_thread ******************************************************
1040 Thread startup function called by pthread_create.
1042 Thread which have a startup.function != NULL are marked as internal
1043 threads. All other threads are threated as normal Java threads.
1045 NOTE: This function is not called directly by pthread_create. The Boehm GC
1046 inserts its own GC_start_routine in between, which then calls
1050 t............the argument passed to pthread_create, ie. a pointer to
1051 a startupinfo struct. CAUTION: When the `psem` semaphore
1052 is posted, the startupinfo struct becomes invalid! (It
1053 is allocated on the stack of threads_start_thread.)
1055 ******************************************************************************/
1057 static void *threads_startup_thread(void *t)
1059 startupinfo *startup;
1060 threadobject *thread;
1061 #if defined(WITH_CLASSPATH_GNU)
1062 java_lang_VMThread *vmt;
1065 threadobject *tnext;
1068 java_objectheader *o;
1069 functionptr function;
1071 #if defined(ENABLE_INTRP)
1072 u1 *intrp_thread_stack;
1074 /* create interpreter stack */
1077 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
1078 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
1081 intrp_thread_stack = NULL;
1084 /* get passed startupinfo structure and the values in there */
1087 t = NULL; /* make sure it's not used wrongly */
1089 thread = startup->thread;
1090 function = startup->function;
1091 psem = startup->psem;
1093 /* Seems like we've encountered a situation where thread->tid was not set by
1094 * pthread_create. We alleviate this problem by waiting for pthread_create
1096 threads_sem_wait(startup->psem_first);
1098 /* set the thread object */
1100 #if defined(__DARWIN__)
1101 thread->mach_thread = mach_thread_self();
1104 threads_init_threadobject(thread);
1105 threads_set_current_threadobject(thread);
1107 /* insert the thread into the threadlist and the threads table */
1109 pthread_mutex_lock(&threadlistlock);
1111 thread->prev = mainthreadobj;
1112 thread->next = tnext = mainthreadobj->next;
1113 mainthreadobj->next = thread;
1114 tnext->prev = thread;
1116 threads_table_add(thread);
1118 pthread_mutex_unlock(&threadlistlock);
1120 /* init data structures of this thread */
1122 lock_init_execution_env(thread);
1124 /* tell threads_startup_thread that we registered ourselves */
1125 /* CAUTION: *startup becomes invalid with this! */
1128 threads_sem_post(psem);
1130 /* set our priority */
1132 threads_set_thread_priority(thread->tid, thread->object->priority);
1134 #if defined(ENABLE_INTRP)
1135 /* set interpreter stack */
1138 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1141 #if defined(ENABLE_JVMTI)
1142 /* fire thread start event */
1145 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1148 /* find and run the Thread.run()V method if no other function was passed */
1150 if (function == NULL) {
1151 /* this is a normal Java thread */
1153 thread->flags |= THREAD_FLAG_JAVA;
1155 #if defined(WITH_CLASSPATH_GNU)
1156 /* We need to start the run method of
1157 java.lang.VMThread. Since this is a final class, we can use
1158 the class object directly. */
1160 c = class_java_lang_VMThread;
1161 #elif defined(WITH_CLASSPATH_CLDC1_1)
1162 c = thread->object->header.vftbl->class;
1165 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1168 vm_abort("threads_startup_thread: run() method not found in class");
1170 /* set ThreadMXBean variables */
1172 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1173 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1175 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1176 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1177 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1178 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1180 #if defined(WITH_CLASSPATH_GNU)
1181 /* we need to start the run method of java.lang.VMThread */
1183 vmt = (java_lang_VMThread *) thread->object->vmThread;
1184 o = (java_objectheader *) vmt;
1186 #elif defined(WITH_CLASSPATH_CLDC1_1)
1187 o = (java_objectheader *) thread->object;
1190 (void) vm_call_method(m, o);
1193 /* this is an internal thread */
1195 thread->flags |= THREAD_FLAG_INTERNAL;
1197 /* set ThreadMXBean variables */
1199 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1200 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1202 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1203 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1204 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1205 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1207 /* call passed function, e.g. finalizer_thread */
1212 #if defined(ENABLE_JVMTI)
1213 /* fire thread end event */
1216 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1219 threads_detach_thread(thread);
1221 /* set ThreadMXBean variables */
1223 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1229 /* threads_start_javathread ***************************************************
1231 Start a thread in the JVM. Only the java thread object exists so far.
1234 object.....the java thread object java.lang.Thread
1236 ******************************************************************************/
1238 void threads_start_javathread(java_lang_Thread *object)
1240 threadobject *thread;
1242 /* create the vm internal threadobject */
1244 thread = NEW(threadobject);
1246 #if defined(ENABLE_STATISTICS)
1248 size_threadobject += sizeof(threadobject);
1251 /* link the two objects together */
1253 thread->object = object;
1255 #if defined(WITH_CLASSPATH_GNU)
1256 assert(object->vmThread);
1257 assert(object->vmThread->vmdata == NULL);
1258 object->vmThread->vmdata = (java_lang_Object *) thread;
1259 #elif defined(WITH_CLASSPATH_CLDC1_1)
1260 object->vm_thread = (java_lang_Object *) thread;
1263 /* actually start the thread */
1264 /* don't pass a function pointer (NULL) since we want Thread.run()V here */
1266 threads_start_thread(thread, NULL);
1270 /* threads_start_thread ********************************************************
1272 Start a thread in the JVM. Both (vm internal and java) thread objects exist.
1275 thread.......the thread object
1276 function.....function to run in the new thread. NULL means that the
1277 "run" method of the object `t` should be called
1279 ******************************************************************************/
1281 void threads_start_thread(threadobject *thread, functionptr function)
1285 pthread_attr_t attr;
1286 startupinfo startup;
1288 /* fill startupinfo structure passed by pthread_create to
1289 * threads_startup_thread */
1291 startup.thread = thread;
1292 startup.function = function; /* maybe we don't call Thread.run()V */
1293 startup.psem = &sem;
1294 startup.psem_first = &sem_first;
1296 threads_sem_init(&sem, 0, 0);
1297 threads_sem_init(&sem_first, 0, 0);
1299 /* initialize thread attribute object */
1301 if (pthread_attr_init(&attr))
1302 vm_abort("pthread_attr_init failed: %s", strerror(errno));
1304 /* initialize thread stacksize */
1306 if (pthread_attr_setstacksize(&attr, opt_stacksize))
1307 vm_abort("pthread_attr_setstacksize failed: %s", strerror(errno));
1309 /* create the thread */
1311 if (pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup))
1312 vm_abort("pthread_create failed: %s", strerror(errno));
1314 /* signal that pthread_create has returned, so thread->tid is valid */
1316 threads_sem_post(&sem_first);
1318 /* wait here until the thread has entered itself into the thread list */
1320 threads_sem_wait(&sem);
1325 sem_destroy(&sem_first);
1329 /* threads_set_thread_priority *************************************************
1331 Set the priority of the given thread.
1334 tid..........thread id
1335 priority.....priority to set
1337 ******************************************************************************/
1339 void threads_set_thread_priority(pthread_t tid, int priority)
1341 struct sched_param schedp;
1344 pthread_getschedparam(tid, &policy, &schedp);
1345 schedp.sched_priority = priority;
1346 pthread_setschedparam(tid, policy, &schedp);
1350 /* threads_attach_current_thread ***********************************************
1352 Attaches the current thread to the VM. Used in JNI.
1354 *******************************************************************************/
1356 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
1358 threadobject *thread;
1360 java_lang_String *s;
1361 java_objectheader *o;
1362 java_lang_Thread *t;
1364 #if defined(ENABLE_JAVASE)
1365 java_lang_ThreadGroup *group;
1369 #if defined(WITH_CLASSPATH_GNU)
1370 java_lang_VMThread *vmt;
1373 /* create a vm internal thread object */
1375 thread = NEW(threadobject);
1377 #if defined(ENABLE_STATISTICS)
1379 size_threadobject += sizeof(threadobject);
1385 /* create a java.lang.Thread object */
1387 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
1394 threads_init_threadobject(thread);
1395 threads_set_current_threadobject(thread);
1396 lock_init_execution_env(thread);
1398 /* insert the thread into the threadlist and the threads table */
1400 pthread_mutex_lock(&threadlistlock);
1402 thread->prev = mainthreadobj;
1403 thread->next = mainthreadobj->next;
1404 mainthreadobj->next = thread;
1405 thread->next->prev = thread;
1407 threads_table_add(thread);
1409 pthread_mutex_unlock(&threadlistlock);
1411 /* mark thread as Java thread */
1413 thread->flags = THREAD_FLAG_JAVA;
1416 thread->flags |= THREAD_FLAG_DAEMON;
1418 #if defined(ENABLE_INTRP)
1419 /* create interpreter stack */
1422 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1423 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
1427 #if defined(WITH_CLASSPATH_GNU)
1428 /* create a java.lang.VMThread object */
1430 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
1435 /* set the thread */
1438 vmt->vmdata = (java_lang_Object *) thread;
1439 #elif defined(WITH_CLASSPATH_CLDC1_1)
1440 t->vm_thread = (java_lang_Object *) thread;
1443 if (vm_aargs != NULL) {
1444 u = utf_new_char(vm_aargs->name);
1445 #if defined(ENABLE_JAVASE)
1446 group = (java_lang_ThreadGroup *) vm_aargs->group;
1451 #if defined(ENABLE_JAVASE)
1452 group = mainthreadobj->object->group;
1456 s = javastring_new(u);
1458 o = (java_objectheader *) thread->object;
1460 #if defined(WITH_CLASSPATH_GNU)
1461 (void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
1463 #elif defined(WITH_CLASSPATH_CLDC1_1)
1464 (void) vm_call_method(method_thread_init, o, s);
1470 #if defined(ENABLE_JAVASE)
1471 /* store the thread group in the object */
1473 thread->object->group = group;
1475 /* add thread to given thread-group */
1477 m = class_resolveclassmethod(group->header.vftbl->class,
1479 utf_java_lang_Thread__V,
1480 class_java_lang_ThreadGroup,
1483 o = (java_objectheader *) group;
1485 (void) vm_call_method(m, o, t);
1495 /* threads_detach_thread *******************************************************
1497 Detaches the passed thread from the VM. Used in JNI.
1499 *******************************************************************************/
1501 bool threads_detach_thread(threadobject *thread)
1503 #if defined(ENABLE_JAVASE)
1504 java_lang_ThreadGroup *group;
1506 java_objectheader *o;
1507 java_lang_Thread *t;
1510 /* Allow lock record pools to be used by other threads. They
1511 cannot be deleted so we'd better not waste them. */
1513 /* XXX We have to find a new way to free lock records */
1514 /* with the new locking algorithm. */
1515 /* lock_record_free_pools(thread->ee.lockrecordpools); */
1517 /* XXX implement uncaught exception stuff (like JamVM does) */
1519 #if defined(ENABLE_JAVASE)
1520 /* remove thread from the thread group */
1522 group = thread->object->group;
1524 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1526 if (group != NULL) {
1527 m = class_resolveclassmethod(group->header.vftbl->class,
1529 utf_java_lang_Thread__V,
1530 class_java_lang_ThreadGroup,
1536 o = (java_objectheader *) group;
1539 (void) vm_call_method(m, o, t);
1546 /* remove thread from thread list and threads table, do this
1549 pthread_mutex_lock(&threadlistlock);
1551 thread->next->prev = thread->prev;
1552 thread->prev->next = thread->next;
1554 threads_table_remove(thread);
1556 pthread_mutex_unlock(&threadlistlock);
1558 /* reset thread id (lock on joinmutex? TWISTI) */
1560 pthread_mutex_lock(&(thread->joinmutex));
1562 pthread_mutex_unlock(&(thread->joinmutex));
1564 /* tell everyone that a thread has finished */
1566 pthread_cond_broadcast(&(thread->joincond));
1568 /* free the vm internal thread object */
1570 FREE(thread, threadobject);
1572 #if defined(ENABLE_STATISTICS)
1574 size_threadobject -= sizeof(threadobject);
1581 /* threads_suspend_thread ******************************************************
1583 Suspend the passed thread. Execution stops until the thread
1584 is explicitly resumend again.
1587 reason.....Reason for suspending this thread.
1589 *******************************************************************************/
1591 bool threads_suspend_thread(threadobject *thread, s4 reason)
1593 /* acquire the suspendmutex */
1594 pthread_mutex_lock(&(thread->suspendmutex));
1596 if (thread->suspended) {
1597 pthread_mutex_unlock(&(thread->suspendmutex));
1601 /* set the reason for the suspension */
1602 thread->suspend_reason = reason;
1604 /* send the suspend signal to the thread */
1605 assert(thread != THREADOBJECT);
1606 pthread_kill(thread->tid, SIGUSR1);
1608 /* REMEMBER: do not release the suspendmutex, this is done
1609 by the thread itself in threads_suspend_ack(). */
1615 /* threads_suspend_ack *********************************************************
1617 Acknowledges the suspension of the current thread.
1620 pc.....The PC where the thread suspended its execution.
1621 sp.....The SP before the thread suspended its execution.
1623 *******************************************************************************/
1625 void threads_suspend_ack(u1* pc, u1* sp)
1627 threadobject *thread;
1629 thread = THREADOBJECT;
1631 assert(thread->suspend_reason != 0);
1633 /* TODO: remember dump memory size */
1635 #if defined(ENABLE_GC_CACAO)
1636 /* inform the GC about the suspension */
1637 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1639 /* check if the GC wants to leave the thread running */
1640 if (!gc_suspend(thread, pc, sp)) {
1642 /* REMEMBER: we do not unlock the suspendmutex because the thread
1643 will suspend itself again at a later time */
1650 /* mark this thread as suspended and remember the PC */
1652 thread->suspended = true;
1654 /* if we are stopping the world, we should send a global ack */
1655 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1656 threads_sem_post(&suspend_ack);
1659 /* release the suspension mutex and wait till we are resumed */
1660 pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
1662 /* TODO: free dump memory */
1664 /* release the suspendmutex */
1665 pthread_mutex_unlock(&(thread->suspendmutex));
1669 /* threads_resume_thread *******************************************************
1671 Resumes the execution of the passed thread.
1673 *******************************************************************************/
1675 bool threads_resume_thread(threadobject *thread)
1677 /* acquire the suspendmutex */
1678 pthread_mutex_lock(&(thread->suspendmutex));
1680 if (!thread->suspended) {
1681 pthread_mutex_unlock(&(thread->suspendmutex));
1685 thread->suspended = false;
1687 /* tell everyone that the thread should resume */
1688 assert(thread != THREADOBJECT);
1689 pthread_cond_broadcast(&(thread->suspendcond));
1691 /* release the suspendmutex */
1692 pthread_mutex_unlock(&(thread->suspendmutex));
1697 /* threads_find_non_daemon_thread **********************************************
1699 Helper function used by threads_join_all_threads for finding
1700 non-daemon threads that are still running.
1702 *******************************************************************************/
1704 /* At the end of the program, we wait for all running non-daemon
1707 static threadobject *threads_find_non_daemon_thread(threadobject *thread)
1709 while (thread != mainthreadobj) {
1710 if (!(thread->flags & THREAD_FLAG_DAEMON))
1713 thread = thread->prev;
1720 /* threads_join_all_threads ****************************************************
1722 Join all non-daemon threads.
1724 *******************************************************************************/
1726 void threads_join_all_threads(void)
1728 threadobject *thread;
1730 pthread_mutex_lock(&threadlistlock);
1732 while ((thread = threads_find_non_daemon_thread(mainthreadobj->prev)) != NULL) {
1733 pthread_mutex_lock(&(thread->joinmutex));
1735 pthread_mutex_unlock(&threadlistlock);
1738 pthread_cond_wait(&(thread->joincond), &(thread->joinmutex));
1740 pthread_mutex_unlock(&(thread->joinmutex));
1742 pthread_mutex_lock(&threadlistlock);
1745 pthread_mutex_unlock(&threadlistlock);
1749 /* threads_timespec_earlier ****************************************************
1751 Return true if timespec tv1 is earlier than timespec tv2.
1754 tv1..........first timespec
1755 tv2..........second timespec
1758 true, if the first timespec is earlier
1760 *******************************************************************************/
1762 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1763 const struct timespec *tv2)
1765 return (tv1->tv_sec < tv2->tv_sec)
1767 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1771 /* threads_current_time_is_earlier_than ****************************************
1773 Check if the current time is earlier than the given timespec.
1776 tv...........the timespec to compare against
1779 true, if the current time is earlier
1781 *******************************************************************************/
1783 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1785 struct timeval tvnow;
1786 struct timespec tsnow;
1788 /* get current time */
1790 if (gettimeofday(&tvnow, NULL) != 0)
1791 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1793 /* convert it to a timespec */
1795 tsnow.tv_sec = tvnow.tv_sec;
1796 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1798 /* compare current time with the given timespec */
1800 return threads_timespec_earlier(&tsnow, tv);
1804 /* threads_wait_with_timeout ***************************************************
1806 Wait until the given point in time on a monitor until either
1807 we are notified, we are interrupted, or the time is up.
1810 t............the current thread
1811 wakeupTime...absolute (latest) wakeup time
1812 If both tv_sec and tv_nsec are zero, this function
1813 waits for an unlimited amount of time.
1816 true.........if the wait has been interrupted,
1817 false........if the wait was ended by notification or timeout
1819 *******************************************************************************/
1821 static bool threads_wait_with_timeout(threadobject *thread,
1822 struct timespec *wakeupTime)
1824 bool wasinterrupted;
1826 /* acquire the waitmutex */
1828 pthread_mutex_lock(&thread->waitmutex);
1830 /* mark us as sleeping */
1832 thread->sleeping = true;
1834 /* wait on waitcond */
1836 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1838 while (!thread->interrupted && !thread->signaled
1839 && threads_current_time_is_earlier_than(wakeupTime))
1841 pthread_cond_timedwait(&thread->waitcond, &thread->waitmutex,
1847 while (!thread->interrupted && !thread->signaled)
1848 pthread_cond_wait(&thread->waitcond, &thread->waitmutex);
1851 /* check if we were interrupted */
1853 wasinterrupted = thread->interrupted;
1855 /* reset all flags */
1857 thread->interrupted = false;
1858 thread->signaled = false;
1859 thread->sleeping = false;
1861 /* release the waitmutex */
1863 pthread_mutex_unlock(&thread->waitmutex);
1865 return wasinterrupted;
1869 /* threads_wait_with_timeout_relative ******************************************
1871 Wait for the given maximum amount of time on a monitor until either
1872 we are notified, we are interrupted, or the time is up.
1875 t............the current thread
1876 millis.......milliseconds to wait
1877 nanos........nanoseconds to wait
1880 true.........if the wait has been interrupted,
1881 false........if the wait was ended by notification or timeout
1883 *******************************************************************************/
1885 bool threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1888 struct timespec wakeupTime;
1890 /* calculate the the (latest) wakeup time */
1892 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1896 return threads_wait_with_timeout(thread, &wakeupTime);
1900 /* threads_calc_absolute_time **************************************************
1902 Calculate the absolute point in time a given number of ms and ns from now.
1905 millis............milliseconds from now
1906 nanos.............nanoseconds from now
1909 *tm...............receives the timespec of the absolute point in time
1911 *******************************************************************************/
1913 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1915 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1918 gettimeofday(&tv, NULL);
1919 tv.tv_sec += millis / 1000;
1921 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1922 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1923 tm->tv_nsec = nsec % 1000000000;
1932 /* threads_thread_interrupt ****************************************************
1934 Interrupt the given thread.
1936 The thread gets the "waitcond" signal and
1937 its interrupted flag is set to true.
1940 thread............the thread to interrupt
1942 *******************************************************************************/
1944 void threads_thread_interrupt(threadobject *thread)
1946 /* Signal the thread a "waitcond" and tell it that it has been
1949 pthread_mutex_lock(&thread->waitmutex);
1951 /* Interrupt blocking system call using a signal. */
1953 pthread_kill(thread->tid, SIGHUP);
1955 if (thread->sleeping)
1956 pthread_cond_signal(&thread->waitcond);
1958 thread->interrupted = true;
1960 pthread_mutex_unlock(&thread->waitmutex);
1964 /* threads_check_if_interrupted_and_reset **************************************
1966 Check if the current thread has been interrupted and reset the
1970 true, if the current thread had been interrupted
1972 *******************************************************************************/
1974 bool threads_check_if_interrupted_and_reset(void)
1976 threadobject *thread;
1979 thread = THREADOBJECT;
1981 /* get interrupted flag */
1983 intr = thread->interrupted;
1985 /* reset interrupted flag */
1987 thread->interrupted = false;
1993 /* threads_thread_has_been_interrupted *****************************************
1995 Check if the given thread has been interrupted
1998 t............the thread to check
2001 true, if the given thread had been interrupted
2003 *******************************************************************************/
2005 bool threads_thread_has_been_interrupted(threadobject *thread)
2007 return thread->interrupted;
2011 /* threads_sleep ***************************************************************
2013 Sleep the current thread for the specified amount of time.
2015 *******************************************************************************/
2017 void threads_sleep(s8 millis, s4 nanos)
2019 threadobject *thread;
2020 struct timespec wakeupTime;
2021 bool wasinterrupted;
2023 thread = THREADOBJECT;
2025 threads_calc_absolute_time(&wakeupTime, millis, nanos);
2027 wasinterrupted = threads_wait_with_timeout(thread, &wakeupTime);
2030 exceptions_throw_interruptedexception();
2034 /* threads_yield ***************************************************************
2036 Yield to the scheduler.
2038 *******************************************************************************/
2040 void threads_yield(void)
2046 /* threads_table_dump *********************************************************
2048 Dump the threads table for debugging purposes.
2051 file..............stream to write to
2053 ******************************************************************************/
2055 #if !defined(NDEBUG) && 0
2056 static void threads_table_dump(FILE *file)
2062 pthread_mutex_lock(&threadlistlock);
2064 size = threads_table.size;
2066 fprintf(file, "======== THREADS TABLE (size %d) ========\n", size);
2068 for (i=0; i<size; ++i) {
2069 index = threads_table.table[i].nextfree;
2071 fprintf(file, "%4d: ", i);
2074 fprintf(file, "free, nextfree = %d\n", (int) index);
2077 fprintf(file, "thread %p\n", (void*) threads_table.table[i].thread);
2081 fprintf(file, "======== END OF THREADS TABLE ========\n");
2083 pthread_mutex_unlock(&threadlistlock);
2088 * These are local overrides for various environment variables in Emacs.
2089 * Please do not remove this and leave it at the end of the file, where
2090 * Emacs will automagically detect them.
2091 * ---------------------------------------------------------------------
2094 * indent-tabs-mode: t
2098 * vim:noexpandtab:sw=4:ts=4: