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 7338 2007-02-13 00:17:22Z twisti $
32 /* XXX cleanup these includes */
37 #include <sys/types.h>
50 #if !defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
51 # include "machine-instr.h"
53 # include "threads/native/generic-primitives.h"
56 #include "mm/gc-common.h"
57 #include "mm/memory.h"
59 #include "native/jni.h"
60 #include "native/native.h"
61 #include "native/include/java_lang_Object.h"
62 #include "native/include/java_lang_String.h"
63 #include "native/include/java_lang_Throwable.h"
64 #include "native/include/java_lang_Thread.h"
66 #if defined(ENABLE_JAVASE)
67 # include "native/include/java_lang_ThreadGroup.h"
70 #if defined(WITH_CLASSPATH_GNU)
71 # include "native/include/java_lang_VMThread.h"
74 #include "threads/threads-common.h"
76 #include "threads/native/threads.h"
78 #include "toolbox/avl.h"
79 #include "toolbox/logging.h"
81 #include "vm/builtin.h"
82 #include "vm/exceptions.h"
83 #include "vm/global.h"
84 #include "vm/stringlocal.h"
87 #include "vm/jit/asmpart.h"
89 #include "vmcore/options.h"
91 #if !defined(__DARWIN__)
92 # if defined(__LINUX__)
93 # define GC_LINUX_THREADS
94 # elif defined(__MIPS__)
95 # define GC_IRIX_THREADS
97 # include <semaphore.h>
98 # if defined(ENABLE_GC_BOEHM)
99 # include "mm/boehm-gc/include/gc.h"
103 #if defined(ENABLE_JVMTI)
104 #include "native/jvmti/cacaodbg.h"
107 #if defined(__DARWIN__)
108 /* Darwin has no working semaphore implementation. This one is taken
112 This is a very simple semaphore implementation for darwin. It
113 is implemented in terms of pthreads calls so it isn't async signal
114 safe. This isn't a problem because signals aren't used to
115 suspend threads on darwin.
118 static int sem_init(sem_t *sem, int pshared, int value)
125 if (pthread_mutex_init(&sem->mutex, NULL) < 0)
128 if (pthread_cond_init(&sem->cond, NULL) < 0)
134 static int sem_post(sem_t *sem)
136 if (pthread_mutex_lock(&sem->mutex) < 0)
141 if (pthread_cond_signal(&sem->cond) < 0) {
142 pthread_mutex_unlock(&sem->mutex);
146 if (pthread_mutex_unlock(&sem->mutex) < 0)
152 static int sem_wait(sem_t *sem)
154 if (pthread_mutex_lock(&sem->mutex) < 0)
157 while (sem->value == 0) {
158 pthread_cond_wait(&sem->cond, &sem->mutex);
163 if (pthread_mutex_unlock(&sem->mutex) < 0)
169 static int sem_destroy(sem_t *sem)
171 if (pthread_cond_destroy(&sem->cond) < 0)
174 if (pthread_mutex_destroy(&sem->mutex) < 0)
179 #endif /* defined(__DARWIN__) */
182 /* internally used constants **************************************************/
184 /* CAUTION: Do not change these values. Boehm GC code depends on them. */
185 #define STOPWORLD_FROM_GC 1
186 #define STOPWORLD_FROM_CLASS_NUMBERING 2
188 #define THREADS_INITIAL_TABLE_SIZE 8
191 /* startupinfo *****************************************************************
193 Struct used to pass info from threads_start_thread to
194 threads_startup_thread.
196 ******************************************************************************/
199 threadobject *thread; /* threadobject for this thread */
200 functionptr function; /* function to run in the new thread */
201 sem_t *psem; /* signals when thread has been entered */
202 /* in the thread list */
203 sem_t *psem_first; /* signals when pthread_create has returned */
207 /* prototypes *****************************************************************/
209 static void threads_table_init(void);
210 static s4 threads_table_add(threadobject *thread);
211 static void threads_table_remove(threadobject *thread);
212 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
214 #if !defined(NDEBUG) && 0
215 static void threads_table_dump(FILE *file);
218 /******************************************************************************/
219 /* GLOBAL VARIABLES */
220 /******************************************************************************/
222 /* the main thread */
223 threadobject *mainthreadobj;
225 static methodinfo *method_thread_init;
227 /* the thread object of the current thread */
228 /* This is either a thread-local variable defined with __thread, or */
229 /* a thread-specific value stored with key threads_current_threadobject_key. */
230 #if defined(HAVE___THREAD)
231 __thread threadobject *threads_current_threadobject;
233 pthread_key_t threads_current_threadobject_key;
236 /* global threads table */
237 static threads_table_t threads_table;
239 /* global compiler mutex */
240 static pthread_mutex_t compiler_mutex;
242 /* global mutex for changing the thread list */
243 static pthread_mutex_t threadlistlock;
245 /* global mutex for stop-the-world */
246 static pthread_mutex_t stopworldlock;
248 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
250 static volatile int stopworldwhere;
252 /* semaphore used for acknowleding thread suspension */
253 static sem_t suspend_ack;
254 #if defined(__MIPS__)
255 static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
256 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
259 static pthread_attr_t threadattr;
261 /* mutexes used by the fake atomic instructions */
262 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
263 pthread_mutex_t _atomic_add_lock = PTHREAD_MUTEX_INITIALIZER;
264 pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
265 pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
269 /* threads_sem_init ************************************************************
271 Initialize a semaphore. Checks against errors and interruptions.
274 sem..............the semaphore to initialize
275 shared...........true if this semaphore will be shared between processes
276 value............the initial value for the semaphore
278 *******************************************************************************/
280 void threads_sem_init(sem_t *sem, bool shared, int value)
287 r = sem_init(sem, shared, value);
290 } while (errno == EINTR);
292 vm_abort("sem_init failed: %s", strerror(errno));
296 /* threads_sem_wait ************************************************************
298 Wait for a semaphore, non-interruptible.
300 IMPORTANT: Always use this function instead of `sem_wait` directly, as
301 `sem_wait` may be interrupted by signals!
304 sem..............the semaphore to wait on
306 *******************************************************************************/
308 void threads_sem_wait(sem_t *sem)
318 } while (errno == EINTR);
320 vm_abort("sem_wait failed: %s", strerror(errno));
324 /* threads_sem_post ************************************************************
326 Increase the count of a semaphore. Checks for errors.
329 sem..............the semaphore to increase the count of
331 *******************************************************************************/
333 void threads_sem_post(sem_t *sem)
339 /* unlike sem_wait, sem_post is not interruptible */
345 vm_abort("sem_post failed: %s", strerror(errno));
349 /* compiler_lock ***************************************************************
351 Enter the compiler lock.
353 ******************************************************************************/
355 void compiler_lock(void)
357 pthread_mutex_lock(&compiler_mutex);
361 /* compiler_unlock *************************************************************
363 Release the compiler lock.
365 ******************************************************************************/
367 void compiler_unlock(void)
369 pthread_mutex_unlock(&compiler_mutex);
373 /* lock_stopworld **************************************************************
375 Enter the stopworld lock, specifying why the world shall be stopped.
378 where........ STOPWORLD_FROM_GC (1) from within GC
379 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
381 ******************************************************************************/
383 void lock_stopworld(int where)
385 pthread_mutex_lock(&stopworldlock);
386 stopworldwhere = where;
390 /* unlock_stopworld ************************************************************
392 Release the stopworld lock.
394 ******************************************************************************/
396 void unlock_stopworld(void)
399 pthread_mutex_unlock(&stopworldlock);
402 #if !defined(__DARWIN__)
403 /* Caller must hold threadlistlock */
404 static int threads_cast_sendsignals(int sig, int count)
407 threadobject *tobj = mainthreadobj;
408 threadobject *self = THREADOBJECT;
414 } while (tobj != mainthreadobj);
417 assert(tobj == mainthreadobj);
421 pthread_kill(tobj->tid, sig);
423 } while (tobj != mainthreadobj);
430 static void threads_cast_darwinstop(void)
432 threadobject *tobj = mainthreadobj;
433 threadobject *self = THREADOBJECT;
438 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
439 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
440 #if defined(__I386__)
441 i386_thread_state_t thread_state;
443 ppc_thread_state_t thread_state;
445 mach_port_t thread = tobj->mach_thread;
448 r = thread_suspend(thread);
450 if (r != KERN_SUCCESS)
451 vm_abort("thread_suspend failed");
453 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
454 &thread_state_count);
456 if (r != KERN_SUCCESS)
457 vm_abort("thread_get_state failed");
459 thread_restartcriticalsection((ucontext_t *) &thread_state);
461 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
464 if (r != KERN_SUCCESS)
465 vm_abort("thread_set_state failed");
469 } while (tobj != mainthreadobj);
472 static void threads_cast_darwinresume(void)
474 threadobject *tobj = mainthreadobj;
475 threadobject *self = THREADOBJECT;
480 mach_port_t thread = tobj->mach_thread;
483 r = thread_resume(thread);
485 if (r != KERN_SUCCESS)
486 vm_abort("thread_resume failed");
490 } while (tobj != mainthreadobj);
495 #if defined(__MIPS__)
496 static void threads_cast_irixresume(void)
498 pthread_mutex_lock(&suspend_ack_lock);
499 pthread_cond_broadcast(&suspend_cond);
500 pthread_mutex_unlock(&suspend_ack_lock);
504 #if !defined(DISABLE_GC)
506 void threads_cast_stopworld(void)
508 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
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 = threads_cast_sendsignals(GC_signum1(), 0);
522 for (i = 0; i < count; i++)
523 threads_sem_wait(&suspend_ack);
526 pthread_mutex_unlock(&threadlistlock);
529 void threads_cast_startworld(void)
531 pthread_mutex_lock(&threadlistlock);
532 #if defined(__DARWIN__)
533 threads_cast_darwinresume();
534 #elif defined(__MIPS__)
535 threads_cast_irixresume();
536 #elif defined(__CYGWIN__)
540 threads_cast_sendsignals(GC_signum2(), -1);
542 pthread_mutex_unlock(&threadlistlock);
547 #if !defined(__DARWIN__)
548 static void threads_sigsuspend_handler(ucontext_t *ctx)
553 /* XXX TWISTI: this is just a quick hack */
554 #if defined(ENABLE_JIT)
555 thread_restartcriticalsection(ctx);
558 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
559 (not POSIX async-safe). */
560 #if defined(__IRIX__)
561 pthread_mutex_lock(&suspend_ack_lock);
562 threads_sem_post(&suspend_ack);
563 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
564 pthread_mutex_unlock(&suspend_ack_lock);
565 #elif defined(__CYGWIN__)
569 threads_sem_post(&suspend_ack);
573 sigdelset(&sigs, sig);
578 /* This function is called from Boehm GC code. */
580 int cacao_suspendhandler(ucontext_t *ctx)
582 if (stopworldwhere != STOPWORLD_FROM_CLASS_NUMBERING)
585 threads_sigsuspend_handler(ctx);
590 #endif /* DISABLE_GC */
592 /* threads_set_current_threadobject ********************************************
594 Set the current thread object.
597 thread.......the thread object to set
599 *******************************************************************************/
601 static void threads_set_current_threadobject(threadobject *thread)
603 #if !defined(HAVE___THREAD)
604 pthread_setspecific(threads_current_threadobject_key, thread);
606 threads_current_threadobject = thread;
611 /* threads_init_threadobject **************************************************
613 Initialize implementation fields of a threadobject.
616 thread............the threadobject
618 ******************************************************************************/
620 static void threads_init_threadobject(threadobject *thread)
622 thread->tid = pthread_self();
626 /* TODO destroy all those things */
627 pthread_mutex_init(&(thread->joinmutex), NULL);
628 pthread_cond_init(&(thread->joincond), NULL);
630 pthread_mutex_init(&(thread->waitmutex), NULL);
631 pthread_cond_init(&(thread->waitcond), NULL);
633 thread->interrupted = false;
634 thread->signaled = false;
635 thread->sleeping = false;
639 /* threads_get_current_threadobject ********************************************
641 Return the threadobject of the current thread.
644 the current threadobject * (an instance of java.lang.Thread)
646 *******************************************************************************/
648 threadobject *threads_get_current_threadobject(void)
654 /* threads_preinit *************************************************************
656 Do some early initialization of stuff required.
658 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
659 is called AFTER this function!
661 *******************************************************************************/
663 void threads_preinit(void)
665 pthread_mutexattr_t mutexattr;
666 pthread_mutexattr_init(&mutexattr);
667 pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
668 pthread_mutex_init(&compiler_mutex, &mutexattr);
669 pthread_mutexattr_destroy(&mutexattr);
671 pthread_mutex_init(&threadlistlock, NULL);
672 pthread_mutex_init(&stopworldlock, NULL);
674 mainthreadobj = NEW(threadobject);
675 mainthreadobj->tid = pthread_self();
676 mainthreadobj->index = 1;
677 mainthreadobj->thinlock = lock_pre_compute_thinlock(mainthreadobj->index);
679 #if !defined(HAVE___THREAD)
680 pthread_key_create(&threads_current_threadobject_key, NULL);
682 threads_set_current_threadobject(mainthreadobj);
684 threads_sem_init(&suspend_ack, 0, 0);
686 /* initialize the threads table */
688 threads_table_init();
690 /* initialize subsystems */
698 /* threads_init ****************************************************************
700 Initializes the threads required by the JVM: main, finalizer.
702 *******************************************************************************/
704 bool threads_init(void)
706 java_lang_String *threadname;
707 threadobject *tempthread;
708 java_objectheader *o;
710 #if defined(ENABLE_JAVASE)
711 java_lang_ThreadGroup *threadgroup;
716 #if defined(WITH_CLASSPATH_GNU)
717 java_lang_VMThread *vmt;
720 tempthread = mainthreadobj;
722 /* XXX We have to find a new way to free lock records */
723 /* with the new locking algorithm. */
724 /* lock_record_free_pools(mainthreadobj->ee.lockrecordpools); */
726 /* This is kinda tricky, we grow the java.lang.Thread object so we
727 can keep the execution environment there. No Thread object must
728 have been created at an earlier time. */
730 class_java_lang_Thread->instancesize = sizeof(threadobject);
732 /* get methods we need in this file */
734 #if defined(WITH_CLASSPATH_GNU)
736 class_resolveclassmethod(class_java_lang_Thread,
738 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
739 class_java_lang_Thread,
743 class_resolveclassmethod(class_java_lang_Thread,
745 utf_new_char("(Ljava/lang/String;)V"),
746 class_java_lang_Thread,
750 if (method_thread_init == NULL)
753 /* create a java.lang.Thread for the main thread */
755 mainthreadobj = (threadobject *) builtin_new(class_java_lang_Thread);
757 if (mainthreadobj == NULL)
760 FREE(tempthread, threadobject);
762 threads_init_threadobject(mainthreadobj);
764 threads_set_current_threadobject(mainthreadobj);
766 lock_init_execution_env(mainthreadobj);
768 mainthreadobj->next = mainthreadobj;
769 mainthreadobj->prev = mainthreadobj;
771 threads_table_add(mainthreadobj);
773 /* mark main thread as Java thread */
775 mainthreadobj->flags = THREAD_FLAG_JAVA;
777 #if defined(ENABLE_INTRP)
778 /* create interpreter stack */
781 MSET(intrp_main_stack, 0, u1, opt_stacksize);
782 mainthreadobj->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
786 threadname = javastring_new(utf_new_char("main"));
788 #if defined(ENABLE_JAVASE)
789 /* allocate and init ThreadGroup */
791 threadgroup = (java_lang_ThreadGroup *)
792 native_new_and_init(class_java_lang_ThreadGroup);
794 if (threadgroup == NULL)
795 throw_exception_exit();
798 #if defined(WITH_CLASSPATH_GNU)
799 /* create a java.lang.VMThread for the main thread */
801 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
804 throw_exception_exit();
808 t = (java_lang_Thread *) mainthreadobj;
811 /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
812 o = (java_objectheader *) mainthreadobj;
814 (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
816 #elif defined(WITH_CLASSPATH_CLDC1_1)
817 /* call public Thread(String name) */
819 o = (java_objectheader *) mainthreadobj;
821 (void) vm_call_method(method_thread_init, o, threadname);
827 #if defined(ENABLE_JAVASE)
828 mainthreadobj->o.group = threadgroup;
830 /* add main thread to java.lang.ThreadGroup */
832 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
834 utf_java_lang_Thread__V,
835 class_java_lang_ThreadGroup,
838 o = (java_objectheader *) threadgroup;
839 t = (java_lang_Thread *) mainthreadobj;
841 (void) vm_call_method(m, o, t);
848 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
850 /* initialize the thread attribute object */
852 if (pthread_attr_init(&threadattr)) {
853 log_println("pthread_attr_init failed: %s", strerror(errno));
857 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
859 /* everything's ok */
865 /* threads_table_init *********************************************************
867 Initialize the global threads table.
869 ******************************************************************************/
871 static void threads_table_init(void)
876 size = THREADS_INITIAL_TABLE_SIZE;
878 threads_table.size = size;
879 threads_table.table = MNEW(threads_table_entry_t, size);
881 /* link the entries in a freelist */
883 for (i=0; i<size; ++i) {
884 threads_table.table[i].nextfree = i+1;
887 /* terminate the freelist */
889 threads_table.table[size-1].nextfree = 0; /* index 0 is never free */
893 /* threads_table_add **********************************************************
895 Add a thread to the global threads table. The index is entered in the
896 threadobject. The thinlock value for the thread is pre-computed.
899 thread............the thread to add
902 The table index for the newly added thread. This value has also been
903 entered in the threadobject.
906 The caller must hold the threadlistlock!
908 ******************************************************************************/
910 static s4 threads_table_add(threadobject *thread)
917 /* table[0] serves as the head of the freelist */
919 index = threads_table.table[0].nextfree;
921 /* if we got a free index, use it */
925 threads_table.table[0].nextfree = threads_table.table[index].nextfree;
926 threads_table.table[index].thread = thread;
927 thread->index = index;
928 thread->thinlock = lock_pre_compute_thinlock(index);
932 /* we must grow the table */
934 oldsize = threads_table.size;
935 newsize = oldsize * 2;
937 threads_table.table = MREALLOC(threads_table.table, threads_table_entry_t,
939 threads_table.size = newsize;
941 /* link the new entries to a free list */
943 for (i=oldsize; i<newsize; ++i) {
944 threads_table.table[i].nextfree = i+1;
947 /* terminate the freelist */
949 threads_table.table[newsize-1].nextfree = 0; /* index 0 is never free */
951 /* use the first of the new entries */
958 /* threads_table_remove *******************************************************
960 Remove a thread from the global threads table.
963 thread............the thread to remove
966 The caller must hold the threadlistlock!
968 ******************************************************************************/
970 static void threads_table_remove(threadobject *thread)
974 index = thread->index;
976 /* put the index into the freelist */
978 threads_table.table[index] = threads_table.table[0];
979 threads_table.table[0].nextfree = index;
981 /* delete the index in the threadobject to discover bugs */
988 /* threads_startup_thread ******************************************************
990 Thread startup function called by pthread_create.
992 Thread which have a startup.function != NULL are marked as internal
993 threads. All other threads are threated as normal Java threads.
995 NOTE: This function is not called directly by pthread_create. The Boehm GC
996 inserts its own GC_start_routine in between, which then calls
1000 t............the argument passed to pthread_create, ie. a pointer to
1001 a startupinfo struct. CAUTION: When the `psem` semaphore
1002 is posted, the startupinfo struct becomes invalid! (It
1003 is allocated on the stack of threads_start_thread.)
1005 ******************************************************************************/
1007 static void *threads_startup_thread(void *t)
1009 startupinfo *startup;
1010 threadobject *thread;
1011 #if defined(WITH_CLASSPATH_GNU)
1012 java_lang_VMThread *vmt;
1015 threadobject *tnext;
1018 java_objectheader *o;
1019 functionptr function;
1021 #if defined(ENABLE_INTRP)
1022 u1 *intrp_thread_stack;
1024 /* create interpreter stack */
1027 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
1028 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
1031 intrp_thread_stack = NULL;
1034 /* get passed startupinfo structure and the values in there */
1037 t = NULL; /* make sure it's not used wrongly */
1039 thread = startup->thread;
1040 function = startup->function;
1041 psem = startup->psem;
1043 /* Seems like we've encountered a situation where thread->tid was not set by
1044 * pthread_create. We alleviate this problem by waiting for pthread_create
1046 threads_sem_wait(startup->psem_first);
1048 /* set the thread object */
1050 #if defined(__DARWIN__)
1051 thread->mach_thread = mach_thread_self();
1053 threads_set_current_threadobject(thread);
1055 /* insert the thread into the threadlist and the threads table */
1057 pthread_mutex_lock(&threadlistlock);
1059 thread->prev = mainthreadobj;
1060 thread->next = tnext = mainthreadobj->next;
1061 mainthreadobj->next = thread;
1062 tnext->prev = thread;
1064 threads_table_add(thread);
1066 pthread_mutex_unlock(&threadlistlock);
1068 /* init data structures of this thread */
1070 lock_init_execution_env(thread);
1072 /* tell threads_startup_thread that we registered ourselves */
1073 /* CAUTION: *startup becomes invalid with this! */
1076 threads_sem_post(psem);
1078 /* set our priority */
1080 threads_set_thread_priority(thread->tid, thread->o.priority);
1082 #if defined(ENABLE_INTRP)
1083 /* set interpreter stack */
1086 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1089 #if defined(ENABLE_JVMTI)
1090 /* fire thread start event */
1093 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1096 /* find and run the Thread.run()V method if no other function was passed */
1098 if (function == NULL) {
1099 /* this is a normal Java thread */
1101 thread->flags |= THREAD_FLAG_JAVA;
1103 #if defined(WITH_CLASSPATH_GNU)
1104 /* We need to start the run method of
1105 java.lang.VMThread. Since this is a final class, we can use
1106 the class object directly. */
1108 c = class_java_lang_VMThread;
1109 #elif defined(WITH_CLASSPATH_CLDC1_1)
1110 c = thread->o.header.vftbl->class;
1113 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1118 /* set ThreadMXBean variables */
1120 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1121 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1123 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1124 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1125 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1126 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1128 #if defined(WITH_CLASSPATH_GNU)
1129 /* we need to start the run method of java.lang.VMThread */
1131 vmt = (java_lang_VMThread *) thread->o.vmThread;
1132 o = (java_objectheader *) vmt;
1134 #elif defined(WITH_CLASSPATH_CLDC1_1)
1135 o = (java_objectheader *) thread;
1138 (void) vm_call_method(m, o);
1141 /* this is an internal thread */
1143 thread->flags |= THREAD_FLAG_INTERNAL;
1145 /* set ThreadMXBean variables */
1147 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1148 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1150 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1151 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1152 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1153 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1155 /* call passed function, e.g. finalizer_thread */
1160 #if defined(ENABLE_JVMTI)
1161 /* fire thread end event */
1164 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1167 threads_detach_thread(thread);
1169 /* set ThreadMXBean variables */
1171 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1177 /* threads_start_thread ********************************************************
1179 Start a thread in the JVM.
1182 thread.......the thread object
1183 function.....function to run in the new thread. NULL means that the
1184 "run" method of the object `t` should be called
1186 ******************************************************************************/
1188 void threads_start_thread(threadobject *thread, functionptr function)
1192 pthread_attr_t attr;
1193 startupinfo startup;
1195 /* fill startupinfo structure passed by pthread_create to
1196 * threads_startup_thread */
1198 startup.thread = thread;
1199 startup.function = function; /* maybe we don't call Thread.run()V */
1200 startup.psem = &sem;
1201 startup.psem_first = &sem_first;
1203 threads_sem_init(&sem, 0, 0);
1204 threads_sem_init(&sem_first, 0, 0);
1206 /* initialize thread attribute object */
1208 if (pthread_attr_init(&attr))
1209 vm_abort("pthread_attr_init failed: %s", strerror(errno));
1211 /* initialize thread stacksize */
1213 if (pthread_attr_setstacksize(&attr, opt_stacksize))
1214 vm_abort("pthread_attr_setstacksize failed: %s", strerror(errno));
1216 /* create the thread */
1218 if (pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup))
1219 vm_abort("pthread_create failed: %s", strerror(errno));
1221 /* signal that pthread_create has returned, so thread->tid is valid */
1223 threads_sem_post(&sem_first);
1225 /* wait here until the thread has entered itself into the thread list */
1227 threads_sem_wait(&sem);
1232 sem_destroy(&sem_first);
1236 /* threads_set_thread_priority *************************************************
1238 Set the priority of the given thread.
1241 tid..........thread id
1242 priority.....priority to set
1244 ******************************************************************************/
1246 void threads_set_thread_priority(pthread_t tid, int priority)
1248 struct sched_param schedp;
1251 #if defined(ENABLE_JAVAME_CLDC1_1)
1252 /* The thread id is zero when a thread is created in Java. The
1253 priority is set later during startup. */
1259 pthread_getschedparam(tid, &policy, &schedp);
1260 schedp.sched_priority = priority;
1261 pthread_setschedparam(tid, policy, &schedp);
1265 /* threads_attach_current_thread ***********************************************
1267 Attaches the current thread to the VM. Used in JNI.
1269 *******************************************************************************/
1271 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
1273 threadobject *thread;
1275 java_lang_String *s;
1276 java_objectheader *o;
1277 java_lang_Thread *t;
1279 #if defined(ENABLE_JAVASE)
1280 java_lang_ThreadGroup *group;
1284 #if defined(WITH_CLASSPATH_GNU)
1285 java_lang_VMThread *vmt;
1288 /* create a java.lang.Thread object */
1290 thread = (threadobject *) builtin_new(class_java_lang_Thread);
1295 /* cast for convenience */
1297 t = (java_lang_Thread *) thread;
1299 threads_init_threadobject(thread);
1300 threads_set_current_threadobject(thread);
1301 lock_init_execution_env(thread);
1303 /* insert the thread into the threadlist and the threads table */
1305 pthread_mutex_lock(&threadlistlock);
1307 thread->prev = mainthreadobj;
1308 thread->next = mainthreadobj->next;
1309 mainthreadobj->next = thread;
1310 thread->next->prev = thread;
1312 threads_table_add(thread);
1314 pthread_mutex_unlock(&threadlistlock);
1316 /* mark thread as Java thread */
1318 thread->flags = THREAD_FLAG_JAVA;
1321 thread->flags |= THREAD_FLAG_DAEMON;
1323 #if defined(ENABLE_INTRP)
1324 /* create interpreter stack */
1327 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1328 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
1332 #if defined(WITH_CLASSPATH_GNU)
1333 /* create a java.lang.VMThread object */
1335 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
1340 /* set the thread */
1345 if (vm_aargs != NULL) {
1346 u = utf_new_char(vm_aargs->name);
1347 #if defined(ENABLE_JAVASE)
1348 group = (java_lang_ThreadGroup *) vm_aargs->group;
1353 #if defined(ENABLE_JAVASE)
1354 group = mainthreadobj->o.group;
1358 s = javastring_new(u);
1360 o = (java_objectheader *) thread;
1362 #if defined(WITH_CLASSPATH_GNU)
1363 (void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
1365 #elif defined(WITH_CLASSPATH_CLDC1_1)
1366 (void) vm_call_method(method_thread_init, o, s);
1372 #if defined(ENABLE_JAVASE)
1373 /* store the thread group in the object */
1375 thread->o.group = group;
1377 /* add thread to given thread-group */
1379 m = class_resolveclassmethod(group->header.vftbl->class,
1381 utf_java_lang_Thread__V,
1382 class_java_lang_ThreadGroup,
1385 o = (java_objectheader *) group;
1387 (void) vm_call_method(m, o, t);
1397 /* threads_detach_thread *******************************************************
1399 Detaches the passed thread from the VM. Used in JNI.
1401 *******************************************************************************/
1403 bool threads_detach_thread(threadobject *thread)
1405 #if defined(ENABLE_JAVASE)
1406 java_lang_ThreadGroup *group;
1408 java_objectheader *o;
1409 java_lang_Thread *t;
1412 /* Allow lock record pools to be used by other threads. They
1413 cannot be deleted so we'd better not waste them. */
1415 /* XXX We have to find a new way to free lock records */
1416 /* with the new locking algorithm. */
1417 /* lock_record_free_pools(thread->ee.lockrecordpools); */
1419 /* XXX implement uncaught exception stuff (like JamVM does) */
1421 #if defined(ENABLE_JAVASE)
1422 /* remove thread from the thread group */
1424 group = thread->o.group;
1426 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1428 if (group != NULL) {
1429 m = class_resolveclassmethod(group->header.vftbl->class,
1431 utf_java_lang_Thread__V,
1432 class_java_lang_ThreadGroup,
1438 o = (java_objectheader *) group;
1439 t = (java_lang_Thread *) thread;
1441 (void) vm_call_method(m, o, t);
1448 /* remove thread from thread list and threads table, do this
1451 pthread_mutex_lock(&threadlistlock);
1453 thread->next->prev = thread->prev;
1454 thread->prev->next = thread->next;
1456 threads_table_remove(thread);
1458 pthread_mutex_unlock(&threadlistlock);
1460 /* reset thread id (lock on joinmutex? TWISTI) */
1462 pthread_mutex_lock(&(thread->joinmutex));
1464 pthread_mutex_unlock(&(thread->joinmutex));
1466 /* tell everyone that a thread has finished */
1468 pthread_cond_broadcast(&(thread->joincond));
1474 /* threads_find_non_daemon_thread **********************************************
1476 Helper function used by threads_join_all_threads for finding
1477 non-daemon threads that are still running.
1479 *******************************************************************************/
1481 /* At the end of the program, we wait for all running non-daemon
1484 static threadobject *threads_find_non_daemon_thread(threadobject *thread)
1486 while (thread != mainthreadobj) {
1487 if (!(thread->flags & THREAD_FLAG_DAEMON))
1490 thread = thread->prev;
1497 /* threads_join_all_threads ****************************************************
1499 Join all non-daemon threads.
1501 *******************************************************************************/
1503 void threads_join_all_threads(void)
1505 threadobject *thread;
1507 pthread_mutex_lock(&threadlistlock);
1509 while ((thread = threads_find_non_daemon_thread(mainthreadobj->prev)) != NULL) {
1510 pthread_mutex_lock(&(thread->joinmutex));
1512 pthread_mutex_unlock(&threadlistlock);
1515 pthread_cond_wait(&(thread->joincond), &(thread->joinmutex));
1517 pthread_mutex_unlock(&(thread->joinmutex));
1519 pthread_mutex_lock(&threadlistlock);
1522 pthread_mutex_unlock(&threadlistlock);
1526 /* threads_timespec_earlier ****************************************************
1528 Return true if timespec tv1 is earlier than timespec tv2.
1531 tv1..........first timespec
1532 tv2..........second timespec
1535 true, if the first timespec is earlier
1537 *******************************************************************************/
1539 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1540 const struct timespec *tv2)
1542 return (tv1->tv_sec < tv2->tv_sec)
1544 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1548 /* threads_current_time_is_earlier_than ****************************************
1550 Check if the current time is earlier than the given timespec.
1553 tv...........the timespec to compare against
1556 true, if the current time is earlier
1558 *******************************************************************************/
1560 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1562 struct timeval tvnow;
1563 struct timespec tsnow;
1565 /* get current time */
1567 if (gettimeofday(&tvnow, NULL) != 0)
1568 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1570 /* convert it to a timespec */
1572 tsnow.tv_sec = tvnow.tv_sec;
1573 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1575 /* compare current time with the given timespec */
1577 return threads_timespec_earlier(&tsnow, tv);
1581 /* threads_wait_with_timeout ***************************************************
1583 Wait until the given point in time on a monitor until either
1584 we are notified, we are interrupted, or the time is up.
1587 t............the current thread
1588 wakeupTime...absolute (latest) wakeup time
1589 If both tv_sec and tv_nsec are zero, this function
1590 waits for an unlimited amount of time.
1593 true.........if the wait has been interrupted,
1594 false........if the wait was ended by notification or timeout
1596 *******************************************************************************/
1598 static bool threads_wait_with_timeout(threadobject *thread,
1599 struct timespec *wakeupTime)
1601 bool wasinterrupted;
1603 /* acquire the waitmutex */
1605 pthread_mutex_lock(&thread->waitmutex);
1607 /* mark us as sleeping */
1609 thread->sleeping = true;
1611 /* wait on waitcond */
1613 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1615 while (!thread->interrupted && !thread->signaled
1616 && threads_current_time_is_earlier_than(wakeupTime))
1618 pthread_cond_timedwait(&thread->waitcond, &thread->waitmutex,
1624 while (!thread->interrupted && !thread->signaled)
1625 pthread_cond_wait(&thread->waitcond, &thread->waitmutex);
1628 /* check if we were interrupted */
1630 wasinterrupted = thread->interrupted;
1632 /* reset all flags */
1634 thread->interrupted = false;
1635 thread->signaled = false;
1636 thread->sleeping = false;
1638 /* release the waitmutex */
1640 pthread_mutex_unlock(&thread->waitmutex);
1642 return wasinterrupted;
1646 /* threads_wait_with_timeout_relative ******************************************
1648 Wait for the given maximum amount of time on a monitor until either
1649 we are notified, we are interrupted, or the time is up.
1652 t............the current thread
1653 millis.......milliseconds to wait
1654 nanos........nanoseconds to wait
1657 true.........if the wait has been interrupted,
1658 false........if the wait was ended by notification or timeout
1660 *******************************************************************************/
1662 bool threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1665 struct timespec wakeupTime;
1667 /* calculate the the (latest) wakeup time */
1669 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1673 return threads_wait_with_timeout(thread, &wakeupTime);
1677 /* threads_calc_absolute_time **************************************************
1679 Calculate the absolute point in time a given number of ms and ns from now.
1682 millis............milliseconds from now
1683 nanos.............nanoseconds from now
1686 *tm...............receives the timespec of the absolute point in time
1688 *******************************************************************************/
1690 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1692 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1695 gettimeofday(&tv, NULL);
1696 tv.tv_sec += millis / 1000;
1698 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1699 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1700 tm->tv_nsec = nsec % 1000000000;
1709 /* threads_thread_interrupt ****************************************************
1711 Interrupt the given thread.
1713 The thread gets the "waitcond" signal and
1714 its interrupted flag is set to true.
1717 thread............the thread to interrupt
1719 *******************************************************************************/
1721 void threads_thread_interrupt(threadobject *thread)
1723 /* Signal the thread a "waitcond" and tell it that it has been
1726 pthread_mutex_lock(&thread->waitmutex);
1728 /* Interrupt blocking system call using a signal. */
1730 pthread_kill(thread->tid, SIGHUP);
1732 if (thread->sleeping)
1733 pthread_cond_signal(&thread->waitcond);
1735 thread->interrupted = true;
1737 pthread_mutex_unlock(&thread->waitmutex);
1741 /* threads_check_if_interrupted_and_reset **************************************
1743 Check if the current thread has been interrupted and reset the
1747 true, if the current thread had been interrupted
1749 *******************************************************************************/
1751 bool threads_check_if_interrupted_and_reset(void)
1753 threadobject *thread;
1756 thread = THREADOBJECT;
1758 /* get interrupted flag */
1760 intr = thread->interrupted;
1762 /* reset interrupted flag */
1764 thread->interrupted = false;
1770 /* threads_thread_has_been_interrupted *****************************************
1772 Check if the given thread has been interrupted
1775 t............the thread to check
1778 true, if the given thread had been interrupted
1780 *******************************************************************************/
1782 bool threads_thread_has_been_interrupted(threadobject *thread)
1784 return thread->interrupted;
1788 /* threads_sleep ***************************************************************
1790 Sleep the current thread for the specified amount of time.
1792 *******************************************************************************/
1794 void threads_sleep(s8 millis, s4 nanos)
1796 threadobject *thread;
1797 struct timespec wakeupTime;
1798 bool wasinterrupted;
1800 thread = THREADOBJECT;
1802 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1804 wasinterrupted = threads_wait_with_timeout(thread, &wakeupTime);
1807 exceptions_throw_interruptedexception();
1811 /* threads_yield ***************************************************************
1813 Yield to the scheduler.
1815 *******************************************************************************/
1817 void threads_yield(void)
1823 /* threads_dump ****************************************************************
1825 Dumps info for all threads running in the JVM. This function is
1826 called when SIGQUIT (<ctrl>-\) is sent to CACAO.
1828 *******************************************************************************/
1830 void threads_dump(void)
1832 threadobject *thread;
1833 java_lang_Thread *t;
1836 thread = mainthreadobj;
1838 /* XXX we should stop the world here */
1840 printf("Full thread dump CACAO "VERSION":\n");
1842 /* iterate over all started threads */
1845 /* get thread object */
1847 t = (java_lang_Thread *) thread;
1849 /* the thread may be currently in initalization, don't print it */
1852 /* get thread name */
1854 #if defined(ENABLE_JAVASE)
1855 name = javastring_toutf(t->name, false);
1856 #elif defined(ENABLE_JAVAME_CLDC1_1)
1861 utf_display_printable_ascii(name);
1864 if (thread->flags & THREAD_FLAG_DAEMON)
1867 #if SIZEOF_VOID_P == 8
1868 printf("prio=%d tid=0x%016lx\n", t->priority, (ptrint) thread->tid);
1870 printf("prio=%d tid=0x%08lx\n", t->priority, (ptrint) thread->tid);
1873 /* dump trace of thread */
1875 stacktrace_dump_trace(thread);
1878 thread = thread->next;
1879 } while ((thread != NULL) && (thread != mainthreadobj));
1883 /* threads_table_dump *********************************************************
1885 Dump the threads table for debugging purposes.
1888 file..............stream to write to
1890 ******************************************************************************/
1892 #if !defined(NDEBUG) && 0
1893 static void threads_table_dump(FILE *file)
1899 pthread_mutex_lock(&threadlistlock);
1901 size = threads_table.size;
1903 fprintf(file, "======== THREADS TABLE (size %d) ========\n", size);
1905 for (i=0; i<size; ++i) {
1906 index = threads_table.table[i].nextfree;
1908 fprintf(file, "%4d: ", i);
1911 fprintf(file, "free, nextfree = %d\n", (int) index);
1914 fprintf(file, "thread %p\n", (void*) threads_table.table[i].thread);
1918 fprintf(file, "======== END OF THREADS TABLE ========\n");
1920 pthread_mutex_unlock(&threadlistlock);
1925 * These are local overrides for various environment variables in Emacs.
1926 * Please do not remove this and leave it at the end of the file, where
1927 * Emacs will automagically detect them.
1928 * ---------------------------------------------------------------------
1931 * indent-tabs-mode: t
1935 * vim:noexpandtab:sw=4:ts=4: