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 7766 2007-04-19 13:24:48Z 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 /* global mutex and condition for joining threads on exit */
250 static pthread_mutex_t mutex_join;
251 static pthread_cond_t cond_join;
253 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
255 static volatile int stopworldwhere;
257 /* semaphore used for acknowleding thread suspension */
258 static sem_t suspend_ack;
259 #if defined(__MIPS__)
260 static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
261 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
264 static pthread_attr_t threadattr;
266 /* mutexes used by the fake atomic instructions */
267 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
268 pthread_mutex_t _atomic_add_lock = PTHREAD_MUTEX_INITIALIZER;
269 pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
270 pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
274 /* threads_sem_init ************************************************************
276 Initialize a semaphore. Checks against errors and interruptions.
279 sem..............the semaphore to initialize
280 shared...........true if this semaphore will be shared between processes
281 value............the initial value for the semaphore
283 *******************************************************************************/
285 void threads_sem_init(sem_t *sem, bool shared, int value)
292 r = sem_init(sem, shared, value);
295 } while (errno == EINTR);
297 vm_abort("sem_init failed: %s", strerror(errno));
301 /* threads_sem_wait ************************************************************
303 Wait for a semaphore, non-interruptible.
305 IMPORTANT: Always use this function instead of `sem_wait` directly, as
306 `sem_wait` may be interrupted by signals!
309 sem..............the semaphore to wait on
311 *******************************************************************************/
313 void threads_sem_wait(sem_t *sem)
323 } while (errno == EINTR);
325 vm_abort("sem_wait failed: %s", strerror(errno));
329 /* threads_sem_post ************************************************************
331 Increase the count of a semaphore. Checks for errors.
334 sem..............the semaphore to increase the count of
336 *******************************************************************************/
338 void threads_sem_post(sem_t *sem)
344 /* unlike sem_wait, sem_post is not interruptible */
350 vm_abort("sem_post failed: %s", strerror(errno));
354 /* lock_stopworld **************************************************************
356 Enter the stopworld lock, specifying why the world shall be stopped.
359 where........ STOPWORLD_FROM_GC (1) from within GC
360 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
362 ******************************************************************************/
364 void lock_stopworld(int where)
366 pthread_mutex_lock(&stopworldlock);
367 stopworldwhere = where;
371 /* unlock_stopworld ************************************************************
373 Release the stopworld lock.
375 ******************************************************************************/
377 void unlock_stopworld(void)
380 pthread_mutex_unlock(&stopworldlock);
383 #if defined(__DARWIN__)
384 /* Caller must hold threadlistlock */
385 static void threads_cast_darwinstop(void)
387 threadobject *tobj = mainthreadobj;
388 threadobject *self = THREADOBJECT;
393 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
394 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
395 #if defined(__I386__)
396 i386_thread_state_t thread_state;
398 ppc_thread_state_t thread_state;
400 mach_port_t thread = tobj->mach_thread;
403 r = thread_suspend(thread);
405 if (r != KERN_SUCCESS)
406 vm_abort("thread_suspend failed");
408 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
409 &thread_state_count);
411 if (r != KERN_SUCCESS)
412 vm_abort("thread_get_state failed");
414 thread_restartcriticalsection((ucontext_t *) &thread_state);
416 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
419 if (r != KERN_SUCCESS)
420 vm_abort("thread_set_state failed");
424 } while (tobj != mainthreadobj);
427 static void threads_cast_darwinresume(void)
429 threadobject *tobj = mainthreadobj;
430 threadobject *self = THREADOBJECT;
435 mach_port_t thread = tobj->mach_thread;
438 r = thread_resume(thread);
440 if (r != KERN_SUCCESS)
441 vm_abort("thread_resume failed");
445 } while (tobj != mainthreadobj);
450 #if defined(__MIPS__)
451 static void threads_cast_irixresume(void)
453 pthread_mutex_lock(&suspend_ack_lock);
454 pthread_cond_broadcast(&suspend_cond);
455 pthread_mutex_unlock(&suspend_ack_lock);
460 #if !defined(__DARWIN__)
461 static void threads_sigsuspend_handler(ucontext_t *ctx)
466 /* XXX TWISTI: this is just a quick hack */
467 #if defined(ENABLE_JIT)
468 thread_restartcriticalsection(ctx);
471 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
472 (not POSIX async-safe). */
473 #if defined(__IRIX__)
474 pthread_mutex_lock(&suspend_ack_lock);
475 threads_sem_post(&suspend_ack);
476 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
477 pthread_mutex_unlock(&suspend_ack_lock);
478 #elif defined(__CYGWIN__)
482 threads_sem_post(&suspend_ack);
486 sigdelset(&sigs, sig);
494 /* threads_stopworld ***********************************************************
496 Stops the world from turning. All threads except the calling one
497 are suspended. The function returns as soon as all threads have
498 acknowledged their suspension.
500 *******************************************************************************/
502 #if !defined(DISABLE_GC)
503 void threads_stopworld(void)
505 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
506 threadobject *tobj = mainthreadobj;
507 threadobject *self = THREADOBJECT;
512 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
513 pthread_mutex_lock(&threadlistlock);
515 #if defined(__DARWIN__)
516 threads_cast_darwinstop();
517 #elif defined(__CYGWIN__)
521 /* count how many threads we suspended */
524 /* suspend all running threads */
527 result = threads_suspend_thread(tobj, SUSPEND_REASON_STOPWORLD);
532 } while (tobj != mainthreadobj);
534 /* wait till all threads are suspended */
535 for (i = 0; i < count; i++)
536 threads_sem_wait(&suspend_ack);
539 pthread_mutex_unlock(&threadlistlock);
541 #endif /* !defined(DISABLE_GC) */
544 /* threads_startworld **********************************************************
546 Starts the world again after it has previously been stopped.
548 *******************************************************************************/
550 #if !defined(DISABLE_GC)
551 void threads_startworld(void)
553 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
554 threadobject *tobj = mainthreadobj;
555 threadobject *self = THREADOBJECT;
559 pthread_mutex_lock(&threadlistlock);
561 #if defined(__DARWIN__)
562 threads_cast_darwinresume();
563 #elif defined(__MIPS__)
564 threads_cast_irixresume();
565 #elif defined(__CYGWIN__)
569 /* resume all thread we haltet */
572 result = threads_resume_thread(tobj);
576 } while (tobj != mainthreadobj);
579 pthread_mutex_unlock(&threadlistlock);
582 #endif /* DISABLE_GC */
585 /* threads_set_current_threadobject ********************************************
587 Set the current thread object.
590 thread.......the thread object to set
592 *******************************************************************************/
594 static void threads_set_current_threadobject(threadobject *thread)
596 #if !defined(HAVE___THREAD)
597 pthread_setspecific(threads_current_threadobject_key, thread);
599 threads_current_threadobject = thread;
604 /* threads_init_threadobject **************************************************
606 Initialize implementation fields of a threadobject.
609 thread............the threadobject
611 ******************************************************************************/
613 static void threads_init_threadobject(threadobject *thread)
615 /* get the pthread id */
617 thread->tid = pthread_self();
621 #if defined(ENABLE_GC_CACAO)
622 thread->flags |= THREAD_FLAG_IN_NATIVE;
623 thread->gc_critical = false;
626 /* TODO destroy all those things */
628 pthread_mutex_init(&(thread->waitmutex), NULL);
629 pthread_cond_init(&(thread->waitcond), NULL);
631 thread->interrupted = false;
632 thread->signaled = false;
633 thread->sleeping = false;
637 /* threads_get_current_threadobject ********************************************
639 Return the threadobject of the current thread.
642 the current threadobject *
644 *******************************************************************************/
646 threadobject *threads_get_current_threadobject(void)
652 /* threads_preinit *************************************************************
654 Do some early initialization of stuff required.
656 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
657 is called AFTER this function!
659 *******************************************************************************/
661 void threads_preinit(void)
663 pthread_mutex_init(&threadlistlock, NULL);
664 pthread_mutex_init(&stopworldlock, NULL);
666 /* initialize exit mutex and condition (on exit we join all
669 pthread_mutex_init(&mutex_join, NULL);
670 pthread_cond_init(&cond_join, NULL);
672 mainthreadobj = NEW(threadobject);
674 #if defined(ENABLE_STATISTICS)
676 size_threadobject += sizeof(threadobject);
679 mainthreadobj->object = NULL;
680 mainthreadobj->tid = pthread_self();
681 mainthreadobj->index = 1;
682 mainthreadobj->thinlock = lock_pre_compute_thinlock(mainthreadobj->index);
684 #if !defined(HAVE___THREAD)
685 pthread_key_create(&threads_current_threadobject_key, NULL);
687 threads_set_current_threadobject(mainthreadobj);
689 threads_sem_init(&suspend_ack, 0, 0);
691 /* initialize the threads table */
693 threads_table_init();
695 /* initialize subsystems */
703 /* threads_init ****************************************************************
705 Initializes the threads required by the JVM: main, finalizer.
707 *******************************************************************************/
709 bool threads_init(void)
711 java_objectheader *threadname;
712 threadobject *tempthread;
713 java_objectheader *o;
715 #if defined(ENABLE_JAVASE)
716 java_lang_ThreadGroup *threadgroup;
721 #if defined(WITH_CLASSPATH_GNU)
722 java_lang_VMThread *vmt;
725 tempthread = mainthreadobj;
727 /* XXX We have to find a new way to free lock records */
728 /* with the new locking algorithm. */
729 /* lock_record_free_pools(mainthreadobj->ee.lockrecordpools); */
732 /* This is kinda tricky, we grow the java.lang.Thread object so we
733 can keep the execution environment there. No Thread object must
734 have been created at an earlier time. */
736 class_java_lang_Thread->instancesize = sizeof(threadobject);
739 /* get methods we need in this file */
741 #if defined(WITH_CLASSPATH_GNU)
743 class_resolveclassmethod(class_java_lang_Thread,
745 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
746 class_java_lang_Thread,
750 class_resolveclassmethod(class_java_lang_Thread,
752 utf_new_char("(Ljava/lang/String;)V"),
753 class_java_lang_Thread,
757 if (method_thread_init == NULL)
760 /* create a vm internal thread object for the main thread */
761 /* XXX Michi: we do not need to do this here, we could use the one
762 created by threads_preinit() */
764 #if defined(ENABLE_GC_CACAO)
765 mainthreadobj = NEW(threadobject);
767 # if defined(ENABLE_STATISTICS)
769 size_threadobject += sizeof(threadobject);
772 mainthreadobj = GCNEW(threadobject);
775 if (mainthreadobj == NULL)
778 /* create a java.lang.Thread for the main thread */
780 mainthreadobj->object = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
782 if (mainthreadobj->object == NULL)
785 FREE(tempthread, threadobject);
787 threads_init_threadobject(mainthreadobj);
788 threads_set_current_threadobject(mainthreadobj);
789 lock_init_execution_env(mainthreadobj);
791 /* thread is running */
793 mainthreadobj->state = THREAD_STATE_RUNNABLE;
795 mainthreadobj->next = mainthreadobj;
796 mainthreadobj->prev = mainthreadobj;
798 threads_table_add(mainthreadobj);
800 /* mark main thread as Java thread */
802 mainthreadobj->flags = THREAD_FLAG_JAVA;
804 #if defined(ENABLE_INTRP)
805 /* create interpreter stack */
808 MSET(intrp_main_stack, 0, u1, opt_stacksize);
809 mainthreadobj->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
813 threadname = javastring_new(utf_new_char("main"));
815 #if defined(ENABLE_JAVASE)
816 /* allocate and init ThreadGroup */
818 threadgroup = (java_lang_ThreadGroup *)
819 native_new_and_init(class_java_lang_ThreadGroup);
821 if (threadgroup == NULL)
825 #if defined(WITH_CLASSPATH_GNU)
826 /* create a java.lang.VMThread for the main thread */
828 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
835 vmt->thread = mainthreadobj->object;
836 vmt->vmdata = (java_lang_Object *) mainthreadobj;
838 /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
839 o = (java_objectheader *) mainthreadobj->object;
841 (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
843 #elif defined(WITH_CLASSPATH_CLDC1_1)
846 mainthreadobj->object->vm_thread = (java_lang_Object *) mainthreadobj;
848 /* call public Thread(String name) */
850 o = (java_objectheader *) mainthreadobj->object;
852 (void) vm_call_method(method_thread_init, o, threadname);
858 #if defined(ENABLE_JAVASE)
859 mainthreadobj->object->group = threadgroup;
861 /* add main thread to java.lang.ThreadGroup */
863 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
865 utf_java_lang_Thread__V,
866 class_java_lang_ThreadGroup,
869 o = (java_objectheader *) threadgroup;
870 t = mainthreadobj->object;
872 (void) vm_call_method(m, o, t);
879 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
881 /* initialize the thread attribute object */
883 if (pthread_attr_init(&threadattr)) {
884 log_println("pthread_attr_init failed: %s", strerror(errno));
888 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
890 /* everything's ok */
896 /* threads_table_init *********************************************************
898 Initialize the global threads table.
900 ******************************************************************************/
902 static void threads_table_init(void)
907 size = THREADS_INITIAL_TABLE_SIZE;
909 threads_table.size = size;
910 threads_table.table = MNEW(threads_table_entry_t, size);
912 /* link the entries in a freelist */
914 for (i=0; i<size; ++i) {
915 threads_table.table[i].nextfree = i+1;
918 /* terminate the freelist */
920 threads_table.table[size-1].nextfree = 0; /* index 0 is never free */
924 /* threads_table_add **********************************************************
926 Add a thread to the global threads table. The index is entered in the
927 threadobject. The thinlock value for the thread is pre-computed.
930 thread............the thread to add
933 The table index for the newly added thread. This value has also been
934 entered in the threadobject.
937 The caller must hold the threadlistlock!
939 ******************************************************************************/
941 static s4 threads_table_add(threadobject *thread)
948 /* table[0] serves as the head of the freelist */
950 index = threads_table.table[0].nextfree;
952 /* if we got a free index, use it */
956 threads_table.table[0].nextfree = threads_table.table[index].nextfree;
957 threads_table.table[index].thread = thread;
958 thread->index = index;
959 thread->thinlock = lock_pre_compute_thinlock(index);
963 /* we must grow the table */
965 oldsize = threads_table.size;
966 newsize = oldsize * 2;
968 threads_table.table = MREALLOC(threads_table.table, threads_table_entry_t,
970 threads_table.size = newsize;
972 /* link the new entries to a free list */
974 for (i=oldsize; i<newsize; ++i) {
975 threads_table.table[i].nextfree = i+1;
978 /* terminate the freelist */
980 threads_table.table[newsize-1].nextfree = 0; /* index 0 is never free */
982 /* use the first of the new entries */
989 /* threads_table_remove *******************************************************
991 Remove a thread from the global threads table.
994 thread............the thread to remove
997 The caller must hold the threadlistlock!
999 ******************************************************************************/
1001 static void threads_table_remove(threadobject *thread)
1005 index = thread->index;
1007 /* put the index into the freelist */
1009 threads_table.table[index] = threads_table.table[0];
1010 threads_table.table[0].nextfree = index;
1012 /* delete the index in the threadobject to discover bugs */
1013 #if !defined(NDEBUG)
1019 /* threads_startup_thread ******************************************************
1021 Thread startup function called by pthread_create.
1023 Thread which have a startup.function != NULL are marked as internal
1024 threads. All other threads are threated as normal Java threads.
1026 NOTE: This function is not called directly by pthread_create. The Boehm GC
1027 inserts its own GC_start_routine in between, which then calls
1031 t............the argument passed to pthread_create, ie. a pointer to
1032 a startupinfo struct. CAUTION: When the `psem` semaphore
1033 is posted, the startupinfo struct becomes invalid! (It
1034 is allocated on the stack of threads_start_thread.)
1036 ******************************************************************************/
1038 static void *threads_startup_thread(void *t)
1040 startupinfo *startup;
1041 threadobject *thread;
1042 #if defined(WITH_CLASSPATH_GNU)
1043 java_lang_VMThread *vmt;
1046 threadobject *tnext;
1049 java_objectheader *o;
1050 functionptr function;
1052 #if defined(ENABLE_INTRP)
1053 u1 *intrp_thread_stack;
1055 /* create interpreter stack */
1058 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
1059 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
1062 intrp_thread_stack = NULL;
1065 /* get passed startupinfo structure and the values in there */
1068 t = NULL; /* make sure it's not used wrongly */
1070 thread = startup->thread;
1071 function = startup->function;
1072 psem = startup->psem;
1074 /* Seems like we've encountered a situation where thread->tid was not set by
1075 * pthread_create. We alleviate this problem by waiting for pthread_create
1077 threads_sem_wait(startup->psem_first);
1079 /* set the thread object */
1081 #if defined(__DARWIN__)
1082 thread->mach_thread = mach_thread_self();
1085 threads_init_threadobject(thread);
1086 threads_set_current_threadobject(thread);
1088 /* thread is running */
1090 thread->state = THREAD_STATE_RUNNABLE;
1092 /* insert the thread into the threadlist and the threads table */
1094 pthread_mutex_lock(&threadlistlock);
1096 thread->prev = mainthreadobj;
1097 thread->next = tnext = mainthreadobj->next;
1098 mainthreadobj->next = thread;
1099 tnext->prev = thread;
1101 threads_table_add(thread);
1103 pthread_mutex_unlock(&threadlistlock);
1105 /* init data structures of this thread */
1107 lock_init_execution_env(thread);
1109 /* tell threads_startup_thread that we registered ourselves */
1110 /* CAUTION: *startup becomes invalid with this! */
1113 threads_sem_post(psem);
1115 /* set our priority */
1117 threads_set_thread_priority(thread->tid, thread->object->priority);
1119 #if defined(ENABLE_INTRP)
1120 /* set interpreter stack */
1123 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1126 #if defined(ENABLE_JVMTI)
1127 /* fire thread start event */
1130 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1133 /* find and run the Thread.run()V method if no other function was passed */
1135 if (function == NULL) {
1136 /* this is a normal Java thread */
1138 thread->flags |= THREAD_FLAG_JAVA;
1140 #if defined(WITH_CLASSPATH_GNU)
1141 /* We need to start the run method of
1142 java.lang.VMThread. Since this is a final class, we can use
1143 the class object directly. */
1145 c = class_java_lang_VMThread;
1146 #elif defined(WITH_CLASSPATH_CLDC1_1)
1147 c = thread->object->header.vftbl->class;
1150 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1153 vm_abort("threads_startup_thread: run() method not found in class");
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 #if defined(WITH_CLASSPATH_GNU)
1166 /* we need to start the run method of java.lang.VMThread */
1168 vmt = (java_lang_VMThread *) thread->object->vmThread;
1169 o = (java_objectheader *) vmt;
1171 #elif defined(WITH_CLASSPATH_CLDC1_1)
1172 o = (java_objectheader *) thread->object;
1175 /* run the thread */
1177 (void) vm_call_method(m, o);
1180 /* this is an internal thread */
1182 thread->flags |= THREAD_FLAG_INTERNAL;
1184 /* set ThreadMXBean variables */
1186 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1187 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1189 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1190 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1191 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1192 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1194 /* call passed function, e.g. finalizer_thread */
1199 #if defined(ENABLE_JVMTI)
1200 /* fire thread end event */
1203 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1206 if (!threads_detach_thread(thread))
1207 vm_abort("threads_startup_thread: threads_detach_thread failed");
1209 /* set ThreadMXBean variables */
1211 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1217 /* threads_start_thread ********************************************************
1219 Start a thread in the JVM. Both (vm internal and java) thread objects exist.
1222 thread.......the thread object
1223 function.....function to run in the new thread. NULL means that the
1224 "run" method of the object `t` should be called
1226 ******************************************************************************/
1228 void threads_start_thread(threadobject *thread, functionptr function)
1232 pthread_attr_t attr;
1233 startupinfo startup;
1235 /* fill startupinfo structure passed by pthread_create to
1236 * threads_startup_thread */
1238 startup.thread = thread;
1239 startup.function = function; /* maybe we don't call Thread.run()V */
1240 startup.psem = &sem;
1241 startup.psem_first = &sem_first;
1243 threads_sem_init(&sem, 0, 0);
1244 threads_sem_init(&sem_first, 0, 0);
1246 /* initialize thread attribute object */
1248 if (pthread_attr_init(&attr))
1249 vm_abort("pthread_attr_init failed: %s", strerror(errno));
1251 /* initialize thread stacksize */
1253 if (pthread_attr_setstacksize(&attr, opt_stacksize))
1254 vm_abort("pthread_attr_setstacksize failed: %s", strerror(errno));
1256 /* create the thread */
1258 if (pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup))
1259 vm_abort("pthread_create failed: %s", strerror(errno));
1261 /* signal that pthread_create has returned, so thread->tid is valid */
1263 threads_sem_post(&sem_first);
1265 /* wait here until the thread has entered itself into the thread list */
1267 threads_sem_wait(&sem);
1272 sem_destroy(&sem_first);
1276 /* threads_set_thread_priority *************************************************
1278 Set the priority of the given thread.
1281 tid..........thread id
1282 priority.....priority to set
1284 ******************************************************************************/
1286 void threads_set_thread_priority(pthread_t tid, int priority)
1288 struct sched_param schedp;
1291 pthread_getschedparam(tid, &policy, &schedp);
1292 schedp.sched_priority = priority;
1293 pthread_setschedparam(tid, policy, &schedp);
1297 /* threads_attach_current_thread ***********************************************
1299 Attaches the current thread to the VM. Used in JNI.
1301 *******************************************************************************/
1303 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
1305 threadobject *thread;
1307 java_objectheader *s;
1308 java_objectheader *o;
1309 java_lang_Thread *t;
1311 #if defined(ENABLE_JAVASE)
1312 java_lang_ThreadGroup *group;
1316 #if defined(WITH_CLASSPATH_GNU)
1317 java_lang_VMThread *vmt;
1320 /* create a vm internal thread object */
1322 thread = NEW(threadobject);
1324 #if defined(ENABLE_STATISTICS)
1326 size_threadobject += sizeof(threadobject);
1332 /* create a java.lang.Thread object */
1334 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
1341 threads_init_threadobject(thread);
1342 threads_set_current_threadobject(thread);
1343 lock_init_execution_env(thread);
1345 /* thread is running */
1347 thread->state = THREAD_STATE_RUNNABLE;
1349 /* insert the thread into the threadlist and the threads table */
1351 pthread_mutex_lock(&threadlistlock);
1353 thread->prev = mainthreadobj;
1354 thread->next = mainthreadobj->next;
1355 mainthreadobj->next = thread;
1356 thread->next->prev = thread;
1358 threads_table_add(thread);
1360 pthread_mutex_unlock(&threadlistlock);
1362 /* mark thread as Java thread */
1364 thread->flags = THREAD_FLAG_JAVA;
1367 thread->flags |= THREAD_FLAG_DAEMON;
1369 #if defined(ENABLE_INTRP)
1370 /* create interpreter stack */
1373 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1374 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
1378 #if defined(WITH_CLASSPATH_GNU)
1379 /* create a java.lang.VMThread object */
1381 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
1386 /* set the thread */
1389 vmt->vmdata = (java_lang_Object *) thread;
1390 #elif defined(WITH_CLASSPATH_CLDC1_1)
1391 t->vm_thread = (java_lang_Object *) thread;
1394 if (vm_aargs != NULL) {
1395 u = utf_new_char(vm_aargs->name);
1396 #if defined(ENABLE_JAVASE)
1397 group = (java_lang_ThreadGroup *) vm_aargs->group;
1402 #if defined(ENABLE_JAVASE)
1403 group = mainthreadobj->object->group;
1407 /* the the thread name */
1409 s = javastring_new(u);
1411 /* for convenience */
1413 o = (java_objectheader *) thread->object;
1415 #if defined(WITH_CLASSPATH_GNU)
1416 (void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
1418 #elif defined(WITH_CLASSPATH_CLDC1_1)
1419 (void) vm_call_method(method_thread_init, o, s);
1425 #if defined(ENABLE_JAVASE)
1426 /* store the thread group in the object */
1428 thread->object->group = group;
1430 /* add thread to given thread-group */
1432 m = class_resolveclassmethod(group->header.vftbl->class,
1434 utf_java_lang_Thread__V,
1435 class_java_lang_ThreadGroup,
1438 o = (java_objectheader *) group;
1440 (void) vm_call_method(m, o, t);
1450 /* threads_detach_thread *******************************************************
1452 Detaches the passed thread from the VM. Used in JNI.
1454 *******************************************************************************/
1456 bool threads_detach_thread(threadobject *thread)
1458 #if defined(ENABLE_JAVASE)
1459 java_lang_ThreadGroup *group;
1461 java_objectheader *o;
1462 java_lang_Thread *t;
1465 /* Allow lock record pools to be used by other threads. They
1466 cannot be deleted so we'd better not waste them. */
1468 /* XXX We have to find a new way to free lock records */
1469 /* with the new locking algorithm. */
1470 /* lock_record_free_pools(thread->ee.lockrecordpools); */
1472 /* XXX implement uncaught exception stuff (like JamVM does) */
1474 #if defined(ENABLE_JAVASE)
1475 /* remove thread from the thread group */
1477 group = thread->object->group;
1479 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1481 if (group != NULL) {
1482 m = class_resolveclassmethod(group->header.vftbl->class,
1484 utf_java_lang_Thread__V,
1485 class_java_lang_ThreadGroup,
1491 o = (java_objectheader *) group;
1494 (void) vm_call_method(m, o, t);
1501 /* thread is terminated */
1503 thread->state = THREAD_STATE_TERMINATED;
1505 /* lock thread list */
1507 pthread_mutex_lock(&threadlistlock);
1509 /* remove thread from thread list and threads table */
1511 thread->next->prev = thread->prev;
1512 thread->prev->next = thread->next;
1514 threads_table_remove(thread);
1516 /* unlock thread list */
1518 pthread_mutex_unlock(&threadlistlock);
1520 /* signal that this thread has finished */
1522 pthread_mutex_lock(&mutex_join);
1523 pthread_cond_signal(&cond_join);
1524 pthread_mutex_unlock(&mutex_join);
1526 /* free the vm internal thread object */
1528 FREE(thread, threadobject);
1530 #if defined(ENABLE_STATISTICS)
1532 size_threadobject -= sizeof(threadobject);
1539 /* threads_suspend_thread ******************************************************
1541 Suspend the passed thread. Execution stops until the thread
1542 is explicitly resumend again.
1545 reason.....Reason for suspending this thread.
1547 *******************************************************************************/
1549 bool threads_suspend_thread(threadobject *thread, s4 reason)
1551 /* acquire the suspendmutex */
1552 pthread_mutex_lock(&(thread->suspendmutex));
1554 if (thread->suspended) {
1555 pthread_mutex_unlock(&(thread->suspendmutex));
1559 /* set the reason for the suspension */
1560 thread->suspend_reason = reason;
1562 /* send the suspend signal to the thread */
1563 assert(thread != THREADOBJECT);
1564 pthread_kill(thread->tid, SIGUSR1);
1566 /* REMEMBER: do not release the suspendmutex, this is done
1567 by the thread itself in threads_suspend_ack(). */
1573 /* threads_suspend_ack *********************************************************
1575 Acknowledges the suspension of the current thread.
1578 pc.....The PC where the thread suspended its execution.
1579 sp.....The SP before the thread suspended its execution.
1581 *******************************************************************************/
1583 void threads_suspend_ack(u1* pc, u1* sp)
1585 threadobject *thread;
1587 thread = THREADOBJECT;
1589 assert(thread->suspend_reason != 0);
1591 /* TODO: remember dump memory size */
1593 #if defined(ENABLE_GC_CACAO)
1594 /* inform the GC about the suspension */
1595 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1597 /* check if the GC wants to leave the thread running */
1598 if (!gc_suspend(thread, pc, sp)) {
1600 /* REMEMBER: we do not unlock the suspendmutex because the thread
1601 will suspend itself again at a later time */
1608 /* mark this thread as suspended and remember the PC */
1610 thread->suspended = true;
1612 /* if we are stopping the world, we should send a global ack */
1613 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1614 threads_sem_post(&suspend_ack);
1617 /* release the suspension mutex and wait till we are resumed */
1618 pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
1620 /* TODO: free dump memory */
1622 /* release the suspendmutex */
1623 pthread_mutex_unlock(&(thread->suspendmutex));
1627 /* threads_resume_thread *******************************************************
1629 Resumes the execution of the passed thread.
1631 *******************************************************************************/
1633 bool threads_resume_thread(threadobject *thread)
1635 /* acquire the suspendmutex */
1636 pthread_mutex_lock(&(thread->suspendmutex));
1638 if (!thread->suspended) {
1639 pthread_mutex_unlock(&(thread->suspendmutex));
1643 thread->suspended = false;
1645 /* tell everyone that the thread should resume */
1646 assert(thread != THREADOBJECT);
1647 pthread_cond_broadcast(&(thread->suspendcond));
1649 /* release the suspendmutex */
1650 pthread_mutex_unlock(&(thread->suspendmutex));
1655 /* threads_find_non_daemon_thread **********************************************
1657 Helper function used by threads_join_all_threads for finding
1658 non-daemon threads that are still running.
1660 *******************************************************************************/
1662 static threadobject *threads_find_non_daemon_thread(void)
1664 threadobject *thread;
1666 /* lock the thread list */
1668 pthread_mutex_lock(&threadlistlock);
1670 /* iterate over all threads */
1672 thread = mainthreadobj->next;
1674 while (thread != mainthreadobj) {
1675 if (!(thread->flags & THREAD_FLAG_DAEMON)) {
1676 /* unlock thread list */
1678 pthread_mutex_unlock(&threadlistlock);
1683 thread = thread->next;
1686 /* unlock thread list */
1688 pthread_mutex_unlock(&threadlistlock);
1694 /* threads_join_all_threads ****************************************************
1696 Join all non-daemon threads.
1698 *******************************************************************************/
1700 void threads_join_all_threads(void)
1702 threadobject *thread;
1704 /* get current thread */
1706 thread = THREADOBJECT;
1708 /* this thread is waiting for all non-daemon threads to exit */
1710 thread->state = THREAD_STATE_WAITING;
1712 /* enter join mutex */
1714 pthread_mutex_lock(&mutex_join);
1716 /* wait for condition as long as we have non-daemon threads */
1718 while (threads_find_non_daemon_thread() != NULL)
1719 pthread_cond_wait(&cond_join, &mutex_join);
1721 /* leave join mutex */
1723 pthread_mutex_unlock(&mutex_join);
1727 /* threads_timespec_earlier ****************************************************
1729 Return true if timespec tv1 is earlier than timespec tv2.
1732 tv1..........first timespec
1733 tv2..........second timespec
1736 true, if the first timespec is earlier
1738 *******************************************************************************/
1740 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1741 const struct timespec *tv2)
1743 return (tv1->tv_sec < tv2->tv_sec)
1745 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1749 /* threads_current_time_is_earlier_than ****************************************
1751 Check if the current time is earlier than the given timespec.
1754 tv...........the timespec to compare against
1757 true, if the current time is earlier
1759 *******************************************************************************/
1761 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1763 struct timeval tvnow;
1764 struct timespec tsnow;
1766 /* get current time */
1768 if (gettimeofday(&tvnow, NULL) != 0)
1769 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1771 /* convert it to a timespec */
1773 tsnow.tv_sec = tvnow.tv_sec;
1774 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1776 /* compare current time with the given timespec */
1778 return threads_timespec_earlier(&tsnow, tv);
1782 /* threads_wait_with_timeout ***************************************************
1784 Wait until the given point in time on a monitor until either
1785 we are notified, we are interrupted, or the time is up.
1788 t............the current thread
1789 wakeupTime...absolute (latest) wakeup time
1790 If both tv_sec and tv_nsec are zero, this function
1791 waits for an unlimited amount of time.
1794 true.........if the wait has been interrupted,
1795 false........if the wait was ended by notification or timeout
1797 *******************************************************************************/
1799 static bool threads_wait_with_timeout(threadobject *thread,
1800 struct timespec *wakeupTime)
1802 bool wasinterrupted;
1804 /* acquire the waitmutex */
1806 pthread_mutex_lock(&thread->waitmutex);
1808 /* mark us as sleeping */
1810 thread->sleeping = true;
1812 /* wait on waitcond */
1814 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1816 while (!thread->interrupted && !thread->signaled
1817 && threads_current_time_is_earlier_than(wakeupTime))
1819 thread->state = THREAD_STATE_TIMED_WAITING;
1821 pthread_cond_timedwait(&thread->waitcond, &thread->waitmutex,
1824 thread->state = THREAD_STATE_RUNNABLE;
1829 while (!thread->interrupted && !thread->signaled) {
1830 thread->state = THREAD_STATE_WAITING;
1832 pthread_cond_wait(&thread->waitcond, &thread->waitmutex);
1834 thread->state = THREAD_STATE_RUNNABLE;
1838 /* check if we were interrupted */
1840 wasinterrupted = thread->interrupted;
1842 /* reset all flags */
1844 thread->interrupted = false;
1845 thread->signaled = false;
1846 thread->sleeping = false;
1848 /* release the waitmutex */
1850 pthread_mutex_unlock(&thread->waitmutex);
1852 return wasinterrupted;
1856 /* threads_wait_with_timeout_relative ******************************************
1858 Wait for the given maximum amount of time on a monitor until either
1859 we are notified, we are interrupted, or the time is up.
1862 t............the current thread
1863 millis.......milliseconds to wait
1864 nanos........nanoseconds to wait
1867 true.........if the wait has been interrupted,
1868 false........if the wait was ended by notification or timeout
1870 *******************************************************************************/
1872 bool threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1875 struct timespec wakeupTime;
1877 /* calculate the the (latest) wakeup time */
1879 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1883 return threads_wait_with_timeout(thread, &wakeupTime);
1887 /* threads_calc_absolute_time **************************************************
1889 Calculate the absolute point in time a given number of ms and ns from now.
1892 millis............milliseconds from now
1893 nanos.............nanoseconds from now
1896 *tm...............receives the timespec of the absolute point in time
1898 *******************************************************************************/
1900 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1902 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1905 gettimeofday(&tv, NULL);
1906 tv.tv_sec += millis / 1000;
1908 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1909 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1910 tm->tv_nsec = nsec % 1000000000;
1919 /* threads_thread_interrupt ****************************************************
1921 Interrupt the given thread.
1923 The thread gets the "waitcond" signal and
1924 its interrupted flag is set to true.
1927 thread............the thread to interrupt
1929 *******************************************************************************/
1931 void threads_thread_interrupt(threadobject *thread)
1933 /* Signal the thread a "waitcond" and tell it that it has been
1936 pthread_mutex_lock(&thread->waitmutex);
1938 /* Interrupt blocking system call using a signal. */
1940 pthread_kill(thread->tid, SIGHUP);
1942 if (thread->sleeping)
1943 pthread_cond_signal(&thread->waitcond);
1945 thread->interrupted = true;
1947 pthread_mutex_unlock(&thread->waitmutex);
1951 /* threads_check_if_interrupted_and_reset **************************************
1953 Check if the current thread has been interrupted and reset the
1957 true, if the current thread had been interrupted
1959 *******************************************************************************/
1961 bool threads_check_if_interrupted_and_reset(void)
1963 threadobject *thread;
1966 thread = THREADOBJECT;
1968 /* get interrupted flag */
1970 intr = thread->interrupted;
1972 /* reset interrupted flag */
1974 thread->interrupted = false;
1980 /* threads_thread_has_been_interrupted *****************************************
1982 Check if the given thread has been interrupted
1985 t............the thread to check
1988 true, if the given thread had been interrupted
1990 *******************************************************************************/
1992 bool threads_thread_has_been_interrupted(threadobject *thread)
1994 return thread->interrupted;
1998 /* threads_sleep ***************************************************************
2000 Sleep the current thread for the specified amount of time.
2002 *******************************************************************************/
2004 void threads_sleep(s8 millis, s4 nanos)
2006 threadobject *thread;
2007 struct timespec wakeupTime;
2008 bool wasinterrupted;
2010 thread = THREADOBJECT;
2012 threads_calc_absolute_time(&wakeupTime, millis, nanos);
2014 wasinterrupted = threads_wait_with_timeout(thread, &wakeupTime);
2017 exceptions_throw_interruptedexception();
2021 /* threads_yield ***************************************************************
2023 Yield to the scheduler.
2025 *******************************************************************************/
2027 void threads_yield(void)
2033 /* threads_table_dump *********************************************************
2035 Dump the threads table for debugging purposes.
2038 file..............stream to write to
2040 ******************************************************************************/
2042 #if !defined(NDEBUG) && 0
2043 static void threads_table_dump(FILE *file)
2049 pthread_mutex_lock(&threadlistlock);
2051 size = threads_table.size;
2053 fprintf(file, "======== THREADS TABLE (size %d) ========\n", size);
2055 for (i=0; i<size; ++i) {
2056 index = threads_table.table[i].nextfree;
2058 fprintf(file, "%4d: ", i);
2061 fprintf(file, "free, nextfree = %d\n", (int) index);
2064 fprintf(file, "thread %p\n", (void*) threads_table.table[i].thread);
2068 fprintf(file, "======== END OF THREADS TABLE ========\n");
2070 pthread_mutex_unlock(&threadlistlock);
2075 * These are local overrides for various environment variables in Emacs.
2076 * Please do not remove this and leave it at the end of the file, where
2077 * Emacs will automagically detect them.
2078 * ---------------------------------------------------------------------
2081 * indent-tabs-mode: t
2085 * vim:noexpandtab:sw=4:ts=4: