1 /* src/threads/posix/thread-posix.c - POSIX thread functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
28 /* XXX cleanup these includes */
33 #include <sys/types.h>
46 #include "mm/gc-common.h"
47 #include "mm/memory.h"
49 #if defined(ENABLE_GC_CACAO)
50 # include "mm/cacao-gc/gc.h"
53 #include "native/jni.h"
54 #include "native/llni.h"
55 #include "native/native.h"
57 #include "native/include/java_lang_Object.h"
58 #include "native/include/java_lang_String.h"
59 #include "native/include/java_lang_Throwable.h"
60 #include "native/include/java_lang_Thread.h"
62 #if defined(ENABLE_JAVASE)
63 # include "native/include/java_lang_ThreadGroup.h"
66 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
67 # include "native/include/java_lang_VMThread.h"
70 #include "threads/lock-common.h"
71 #include "threads/mutex.h"
72 #include "threads/threadlist.h"
73 #include "threads/thread.h"
75 #include "toolbox/logging.h"
77 #include "vm/builtin.h"
78 #include "vm/exceptions.h"
79 #include "vm/global.h"
80 #include "vm/stringlocal.h"
83 #include "vm/jit/asmpart.h"
85 #include "vmcore/options.h"
87 #if defined(ENABLE_STATISTICS)
88 # include "vmcore/statistics.h"
91 #if !defined(__DARWIN__)
92 # include <semaphore.h>
95 #if defined(__LINUX__)
96 # define GC_LINUX_THREADS
97 #elif defined(__IRIX__)
98 # define GC_IRIX_THREADS
99 #elif defined(__DARWIN__)
100 # define GC_DARWIN_THREADS
103 #if defined(ENABLE_GC_BOEHM)
104 /* We need to include Boehm's gc.h here because it overrides
105 pthread_create and friends. */
106 # include "mm/boehm-gc/include/gc.h"
109 #if defined(ENABLE_JVMTI)
110 #include "native/jvmti/cacaodbg.h"
113 #if defined(__DARWIN__)
114 /* Darwin has no working semaphore implementation. This one is taken
118 This is a very simple semaphore implementation for darwin. It
119 is implemented in terms of pthreads calls so it isn't async signal
120 safe. This isn't a problem because signals aren't used to
121 suspend threads on darwin.
124 static int sem_init(sem_t *sem, int pshared, int value)
131 mutex_init(&sem->mutex);
133 if (pthread_cond_init(&sem->cond, NULL) < 0)
139 static int sem_post(sem_t *sem)
141 mutex_lock(&sem->mutex);
145 if (pthread_cond_signal(&sem->cond) < 0) {
146 mutex_unlock(&sem->mutex);
150 mutex_unlock(&sem->mutex);
155 static int sem_wait(sem_t *sem)
157 mutex_lock(&sem->mutex);
159 while (sem->value == 0) {
160 pthread_cond_wait(&sem->cond, &sem->mutex);
165 mutex_unlock(&sem->mutex);
170 static int sem_destroy(sem_t *sem)
172 if (pthread_cond_destroy(&sem->cond) < 0)
175 mutex_destroy(&sem->mutex);
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
189 /* startupinfo *****************************************************************
191 Struct used to pass info from threads_start_thread to
192 threads_startup_thread.
194 ******************************************************************************/
197 threadobject *thread; /* threadobject for this thread */
198 functionptr function; /* function to run in the new thread */
199 sem_t *psem; /* signals when thread has been entered */
200 /* in the thread list */
201 sem_t *psem_first; /* signals when pthread_create has returned */
205 /* prototypes *****************************************************************/
207 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
210 /******************************************************************************/
211 /* GLOBAL VARIABLES */
212 /******************************************************************************/
214 /* the thread object of the current thread */
215 /* This is either a thread-local variable defined with __thread, or */
216 /* a thread-specific value stored with key threads_current_threadobject_key. */
217 #if defined(HAVE___THREAD)
218 __thread threadobject *thread_current;
220 pthread_key_t thread_current_key;
223 /* global mutex for stop-the-world */
224 static mutex_t stopworldlock;
226 #if defined(ENABLE_GC_CACAO)
227 /* global mutex for the GC */
228 static mutex_t mutex_gc;
231 /* global mutex and condition for joining threads on exit */
232 static mutex_t mutex_join;
233 static pthread_cond_t cond_join;
235 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
237 static volatile int stopworldwhere;
239 #if defined(ENABLE_GC_CACAO)
241 /* semaphore used for acknowleding thread suspension */
242 static sem_t suspend_ack;
243 #if defined(__IRIX__)
244 static mutex_t suspend_ack_lock = MUTEX_INITIALIZER;
245 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
248 #endif /* ENABLE_GC_CACAO */
251 /* threads_sem_init ************************************************************
253 Initialize a semaphore. Checks against errors and interruptions.
256 sem..............the semaphore to initialize
257 shared...........true if this semaphore will be shared between processes
258 value............the initial value for the semaphore
260 *******************************************************************************/
262 void threads_sem_init(sem_t *sem, bool shared, int value)
269 r = sem_init(sem, shared, value);
272 } while (errno == EINTR);
274 vm_abort("sem_init failed: %s", strerror(errno));
278 /* threads_sem_wait ************************************************************
280 Wait for a semaphore, non-interruptible.
282 IMPORTANT: Always use this function instead of `sem_wait` directly, as
283 `sem_wait` may be interrupted by signals!
286 sem..............the semaphore to wait on
288 *******************************************************************************/
290 void threads_sem_wait(sem_t *sem)
300 } while (errno == EINTR);
302 vm_abort("sem_wait failed: %s", strerror(errno));
306 /* threads_sem_post ************************************************************
308 Increase the count of a semaphore. Checks for errors.
311 sem..............the semaphore to increase the count of
313 *******************************************************************************/
315 void threads_sem_post(sem_t *sem)
321 /* unlike sem_wait, sem_post is not interruptible */
327 vm_abort("sem_post failed: %s", strerror(errno));
331 /* lock_stopworld **************************************************************
333 Enter the stopworld lock, specifying why the world shall be stopped.
336 where........ STOPWORLD_FROM_GC (1) from within GC
337 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
339 ******************************************************************************/
341 void lock_stopworld(int where)
343 mutex_lock(&stopworldlock);
344 /* stopworldwhere = where; */
348 /* unlock_stopworld ************************************************************
350 Release the stopworld lock.
352 ******************************************************************************/
354 void unlock_stopworld(void)
356 /* stopworldwhere = 0; */
357 mutex_unlock(&stopworldlock);
360 /* XXX We disable that whole bunch of code until we have the exact-GC
361 running. Some of it may only be needed by the old Boehm-based
362 suspension handling. */
366 #if !defined(__DARWIN__)
367 /* Caller must hold threadlistlock */
368 static s4 threads_cast_sendsignals(s4 sig)
376 /* iterate over all started threads */
380 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
381 /* don't send the signal to ourself */
386 /* don't send the signal to NEW threads (because they are not
387 completely initialized) */
389 if (t->state == THREAD_STATE_NEW)
392 /* send the signal */
394 pthread_kill(t->tid, sig);
396 /* increase threads count */
406 static void threads_cast_darwinstop(void)
408 threadobject *tobj = mainthreadobj;
409 threadobject *self = THREADOBJECT;
414 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
415 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
416 #if defined(__I386__)
417 i386_thread_state_t thread_state;
419 ppc_thread_state_t thread_state;
421 mach_port_t thread = tobj->mach_thread;
424 r = thread_suspend(thread);
426 if (r != KERN_SUCCESS)
427 vm_abort("thread_suspend failed");
429 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
430 &thread_state_count);
432 if (r != KERN_SUCCESS)
433 vm_abort("thread_get_state failed");
435 md_critical_section_restart((ucontext_t *) &thread_state);
437 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
440 if (r != KERN_SUCCESS)
441 vm_abort("thread_set_state failed");
445 } while (tobj != mainthreadobj);
448 static void threads_cast_darwinresume(void)
450 threadobject *tobj = mainthreadobj;
451 threadobject *self = THREADOBJECT;
456 mach_port_t thread = tobj->mach_thread;
459 r = thread_resume(thread);
461 if (r != KERN_SUCCESS)
462 vm_abort("thread_resume failed");
466 } while (tobj != mainthreadobj);
471 #if defined(__IRIX__)
472 static void threads_cast_irixresume(void)
474 mutex_lock(&suspend_ack_lock);
475 pthread_cond_broadcast(&suspend_cond);
476 mutex_unlock(&suspend_ack_lock);
480 #if defined(ENABLE_GC_BOEHM) && !defined(__DARWIN__)
481 static void threads_sigsuspend_handler(ucontext_t *_uc)
486 /* XXX TWISTI: this is just a quick hack */
487 #if defined(ENABLE_JIT)
488 md_critical_section_restart(_uc);
491 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
492 (not POSIX async-safe). */
493 #if defined(__IRIX__)
494 mutex_lock(&suspend_ack_lock);
495 threads_sem_post(&suspend_ack);
496 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
497 mutex_unlock(&suspend_ack_lock);
498 #elif defined(__CYGWIN__)
505 sigdelset(&sigs, sig);
512 /* threads_stopworld ***********************************************************
514 Stops the world from turning. All threads except the calling one
515 are suspended. The function returns as soon as all threads have
516 acknowledged their suspension.
518 *******************************************************************************/
520 void threads_stopworld(void)
522 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
529 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
531 /* lock the threads lists */
535 #if defined(__DARWIN__)
536 /*threads_cast_darwinstop();*/
538 #elif defined(__CYGWIN__)
544 DEBUGTHREADS("stops World", self);
548 /* suspend all running threads */
549 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
550 /* don't send the signal to ourself */
555 /* don't send the signal to NEW threads (because they are not
556 completely initialized) */
558 if (t->state == THREAD_STATE_NEW)
561 /* send the signal */
563 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
566 /* increase threads count */
571 /* wait for all threads signaled to suspend */
572 for (i = 0; i < count; i++)
573 threads_sem_wait(&suspend_ack);
576 /* ATTENTION: Don't unlock the threads-lists here so that
577 non-signaled NEW threads can't change their state and execute
582 /* threads_startworld **********************************************************
584 Starts the world again after it has previously been stopped.
586 *******************************************************************************/
588 void threads_startworld(void)
590 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
597 #if defined(__DARWIN__)
598 /*threads_cast_darwinresume();*/
600 #elif defined(__IRIX__)
601 threads_cast_irixresume();
602 #elif defined(__CYGWIN__)
608 DEBUGTHREADS("starts World", self);
612 /* resume all thread we haltet */
613 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
614 /* don't send the signal to ourself */
619 /* don't send the signal to NEW threads (because they are not
620 completely initialized) */
622 if (t->state == THREAD_STATE_NEW)
625 /* send the signal */
627 result = threads_resume_thread(t);
630 /* increase threads count */
635 /* wait for all threads signaled to suspend */
636 for (i = 0; i < count; i++)
637 threads_sem_wait(&suspend_ack);
641 /* unlock the threads lists */
651 /* threads_impl_thread_init ****************************************************
653 Initialize OS-level locking constructs in threadobject.
656 t....the threadobject
658 *******************************************************************************/
660 void threads_impl_thread_init(threadobject *t)
664 /* initialize the mutex and the condition */
666 mutex_init(&t->flc_lock);
668 result = pthread_cond_init(&t->flc_cond, NULL);
670 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
672 mutex_init(&(t->waitmutex));
674 result = pthread_cond_init(&(t->waitcond), NULL);
676 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
678 mutex_init(&(t->suspendmutex));
680 result = pthread_cond_init(&(t->suspendcond), NULL);
682 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
685 /* threads_impl_thread_clear ***************************************************
687 Clears all fields in threadobject the way an MZERO would have
688 done. MZERO cannot be used anymore because it would mess up the
692 t....the threadobject
694 *******************************************************************************/
696 void threads_impl_thread_clear(threadobject *t)
708 #if defined(__DARWIN__)
712 t->interrupted = false;
715 t->suspended = false;
716 t->suspend_reason = 0;
720 t->_exceptionptr = NULL;
721 t->_stackframeinfo = NULL;
722 t->_localref_table = NULL;
724 #if defined(ENABLE_INTRP)
725 t->_global_sp = NULL;
728 #if defined(ENABLE_GC_CACAO)
729 t->gc_critical = false;
735 MZERO(&t->dumpinfo, dumpinfo_t, 1);
738 /* threads_impl_thread_reuse ***************************************************
740 Resets some implementation fields in threadobject. This was
741 previously done in threads_impl_thread_new.
744 t....the threadobject
746 *******************************************************************************/
748 void threads_impl_thread_reuse(threadobject *t)
750 /* get the pthread id */
752 t->tid = pthread_self();
754 #if defined(ENABLE_DEBUG_FILTER)
755 /* Initialize filter counters */
756 t->filterverbosecallctr[0] = 0;
757 t->filterverbosecallctr[1] = 0;
761 t->tracejavacallindent = 0;
762 t->tracejavacallcount = 0;
769 /* not really needed */
770 t->flc_object = NULL;
774 /* threads_impl_thread_free ****************************************************
776 Cleanup thread stuff.
779 t....the threadobject
781 *******************************************************************************/
785 void threads_impl_thread_free(threadobject *t)
789 /* Destroy the mutex and the condition. */
791 mutex_destroy(&(t->flc_lock));
793 result = pthread_cond_destroy(&(t->flc_cond));
796 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
798 mutex_destroy(&(t->waitmutex));
800 result = pthread_cond_destroy(&(t->waitcond));
803 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
805 mutex_destroy(&(t->suspendmutex));
807 result = pthread_cond_destroy(&(t->suspendcond));
810 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
815 /* threads_impl_preinit ********************************************************
817 Do some early initialization of stuff required.
819 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
820 is called AFTER this function!
822 *******************************************************************************/
824 void threads_impl_preinit(void)
828 mutex_init(&stopworldlock);
830 /* initialize exit mutex and condition (on exit we join all
833 mutex_init(&mutex_join);
835 result = pthread_cond_init(&cond_join, NULL);
837 vm_abort_errnum(result, "threads_impl_preinit: pthread_cond_init failed");
839 #if defined(ENABLE_GC_CACAO)
840 /* initialize the GC mutex & suspend semaphore */
842 mutex_init(&mutex_gc);
843 threads_sem_init(&suspend_ack, 0, 0);
846 #if !defined(HAVE___THREAD)
847 result = pthread_key_create(&thread_current_key, NULL);
849 vm_abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
854 /* threads_mutex_gc_lock *******************************************************
856 Enter the global GC mutex.
858 *******************************************************************************/
860 #if defined(ENABLE_GC_CACAO)
861 void threads_mutex_gc_lock(void)
863 mutex_lock(&mutex_gc);
868 /* threads_mutex_gc_unlock *****************************************************
870 Leave the global GC mutex.
872 *******************************************************************************/
874 #if defined(ENABLE_GC_CACAO)
875 void threads_mutex_gc_unlock(void)
877 mutex_unlock(&mutex_gc);
881 /* threads_mutex_join_lock *****************************************************
883 Enter the join mutex.
885 *******************************************************************************/
887 void threads_mutex_join_lock(void)
889 mutex_lock(&mutex_join);
893 /* threads_mutex_join_unlock ***************************************************
895 Leave the join mutex.
897 *******************************************************************************/
899 void threads_mutex_join_unlock(void)
901 mutex_unlock(&mutex_join);
905 /* threads_impl_init ***********************************************************
907 Initializes the implementation specific bits.
909 *******************************************************************************/
911 void threads_impl_init(void)
916 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
918 /* Initialize the thread attribute object. */
920 result = pthread_attr_init(&attr);
923 vm_abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
925 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
928 vm_abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
932 /* threads_startup_thread ******************************************************
934 Thread startup function called by pthread_create.
936 Thread which have a startup.function != NULL are marked as internal
937 threads. All other threads are threated as normal Java threads.
939 NOTE: This function is not called directly by pthread_create. The Boehm GC
940 inserts its own GC_start_routine in between, which then calls
944 arg..........the argument passed to pthread_create, ie. a pointer to
945 a startupinfo struct. CAUTION: When the `psem` semaphore
946 is posted, the startupinfo struct becomes invalid! (It
947 is allocated on the stack of threads_start_thread.)
949 ******************************************************************************/
951 static void *threads_startup_thread(void *arg)
953 startupinfo *startup;
955 java_lang_Thread *object;
956 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
957 java_lang_VMThread *vmt;
963 functionptr function;
965 #if defined(ENABLE_GC_BOEHM)
966 # if !defined(__DARWIN__)
967 struct GC_stack_base sb;
972 #if defined(ENABLE_INTRP)
973 u1 *intrp_thread_stack;
976 #if defined(ENABLE_INTRP)
977 /* create interpreter stack */
980 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
981 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
984 intrp_thread_stack = NULL;
987 /* get passed startupinfo structure and the values in there */
992 function = startup->function;
993 psem = startup->psem;
995 /* Seems like we've encountered a situation where thread->tid was
996 not set by pthread_create. We alleviate this problem by waiting
997 for pthread_create to return. */
999 threads_sem_wait(startup->psem_first);
1001 #if defined(__DARWIN__)
1002 t->mach_thread = mach_thread_self();
1005 /* Now that we are in the new thread, we can store the internal
1006 thread data-structure in the TSD. */
1008 thread_set_current(t);
1010 #if defined(ENABLE_GC_BOEHM)
1011 # if defined(__DARWIN__)
1012 // This is currently not implemented in Boehm-GC. Just fail silently.
1014 /* Register the thread with Boehm-GC. This must happen before the
1015 thread allocates any memory from the GC heap.*/
1017 result = GC_get_stack_base(&sb);
1020 vm_abort("threads_startup_thread: GC_get_stack_base failed: result=%d", result);
1022 GC_register_my_thread(&sb);
1026 /* get the java.lang.Thread object for this thread */
1028 object = (java_lang_Thread *) thread_get_object(t);
1030 /* set our priority */
1032 threads_set_thread_priority(t->tid, LLNI_field_direct(object, priority));
1034 /* Thread is completely initialized. */
1036 thread_set_state_runnable(t);
1038 /* tell threads_startup_thread that we registered ourselves */
1039 /* CAUTION: *startup becomes invalid with this! */
1042 threads_sem_post(psem);
1044 #if defined(ENABLE_INTRP)
1045 /* set interpreter stack */
1048 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1051 #if defined(ENABLE_JVMTI)
1052 /* fire thread start event */
1055 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1058 DEBUGTHREADS("starting", t);
1060 /* find and run the Thread.run()V method if no other function was passed */
1062 if (function == NULL) {
1063 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1064 /* We need to start the run method of
1065 java.lang.VMThread. Since this is a final class, we can use
1066 the class object directly. */
1068 c = class_java_lang_VMThread;
1069 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1070 LLNI_class_get(object, c);
1072 # error unknown classpath configuration
1075 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1078 vm_abort("threads_startup_thread: run() method not found in class");
1080 /* set ThreadMXBean variables */
1082 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1083 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1085 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1086 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1087 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1088 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1090 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1091 /* we need to start the run method of java.lang.VMThread */
1093 LLNI_field_get_ref(object, vmThread, vmt);
1094 o = (java_handle_t *) vmt;
1096 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1097 o = (java_handle_t *) object;
1099 # error unknown classpath configuration
1102 /* Run the thread. */
1104 (void) vm_call_method(m, o);
1107 /* set ThreadMXBean variables */
1109 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1110 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1112 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1113 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1114 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1115 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1117 /* call passed function, e.g. finalizer_thread */
1122 DEBUGTHREADS("stopping", t);
1124 #if defined(ENABLE_JVMTI)
1125 /* fire thread end event */
1128 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1131 /* We ignore the return value. */
1133 (void) thread_detach_current_thread();
1135 /* set ThreadMXBean variables */
1137 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1143 /* threads_impl_thread_start ***************************************************
1145 Start a thread in the JVM. Both (vm internal and java) thread
1149 thread....the thread object
1150 f.........function to run in the new thread. NULL means that the
1151 "run" method of the object `t` should be called
1153 ******************************************************************************/
1155 void threads_impl_thread_start(threadobject *thread, functionptr f)
1159 pthread_attr_t attr;
1160 startupinfo startup;
1163 /* fill startupinfo structure passed by pthread_create to
1164 * threads_startup_thread */
1166 startup.thread = thread;
1167 startup.function = f; /* maybe we don't call Thread.run()V */
1168 startup.psem = &sem;
1169 startup.psem_first = &sem_first;
1171 threads_sem_init(&sem, 0, 0);
1172 threads_sem_init(&sem_first, 0, 0);
1174 /* Initialize thread attributes. */
1176 result = pthread_attr_init(&attr);
1179 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
1181 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1184 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
1186 /* initialize thread stacksize */
1188 result = pthread_attr_setstacksize(&attr, opt_stacksize);
1191 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
1193 /* create the thread */
1195 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1198 vm_abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
1200 /* destroy the thread attributes */
1202 result = pthread_attr_destroy(&attr);
1205 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
1207 /* signal that pthread_create has returned, so thread->tid is valid */
1209 threads_sem_post(&sem_first);
1211 /* wait here until the thread has entered itself into the thread list */
1213 threads_sem_wait(&sem);
1218 sem_destroy(&sem_first);
1222 /* threads_set_thread_priority *************************************************
1224 Set the priority of the given thread.
1227 tid..........thread id
1228 priority.....priority to set
1230 ******************************************************************************/
1232 void threads_set_thread_priority(pthread_t tid, int priority)
1234 struct sched_param schedp;
1237 pthread_getschedparam(tid, &policy, &schedp);
1238 schedp.sched_priority = priority;
1239 pthread_setschedparam(tid, policy, &schedp);
1244 * Detaches the current thread from the VM.
1246 * @return true on success, false otherwise
1248 bool thread_detach_current_thread(void)
1252 java_lang_Thread *object;
1254 #if defined(ENABLE_JAVASE)
1255 java_lang_ThreadGroup *group;
1262 t = thread_get_current();
1268 /* If the given thread has already been detached, this operation
1271 result = thread_is_attached(t);
1273 if (result == false)
1276 DEBUGTHREADS("detaching", t);
1278 object = (java_lang_Thread *) thread_get_object(t);
1280 #if defined(ENABLE_JAVASE)
1281 LLNI_field_get_ref(object, group, group);
1283 /* If there's an uncaught exception, call uncaughtException on the
1284 thread's exception handler, or the thread's group if this is
1287 e = exceptions_get_and_clear_exception();
1290 /* We use the type void* for handler here, as it's not trivial
1291 to build the java_lang_Thread_UncaughtExceptionHandler
1292 header file with cacaoh. */
1294 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1295 LLNI_field_get_ref(object, exceptionHandler, handler);
1296 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1297 LLNI_field_get_ref(object, uncaughtExceptionHandler, handler);
1300 if (handler != NULL) {
1301 LLNI_class_get(handler, c);
1302 o = (java_handle_t *) handler;
1305 LLNI_class_get(group, c);
1306 o = (java_handle_t *) group;
1309 m = class_resolveclassmethod(c,
1310 utf_uncaughtException,
1311 utf_java_lang_Thread_java_lang_Throwable__V,
1318 (void) vm_call_method(m, o, object, e);
1320 if (exceptions_get_exception())
1324 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1326 /* Remove thread from the thread group. */
1328 if (group != NULL) {
1329 LLNI_class_get(group, c);
1331 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1332 m = class_resolveclassmethod(c,
1334 utf_java_lang_Thread__V,
1335 class_java_lang_ThreadGroup,
1337 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1338 m = class_resolveclassmethod(c,
1340 utf_java_lang_Thread__V,
1341 class_java_lang_ThreadGroup,
1344 # error unknown classpath configuration
1350 o = (java_handle_t *) group;
1352 (void) vm_call_method(m, o, object);
1354 if (exceptions_get_exception())
1357 /* Reset the threadgroup in the Java thread object (Mauve
1358 test: gnu/testlet/java/lang/Thread/getThreadGroup). */
1360 LLNI_field_set_ref(object, group, NULL);
1364 /* Thread has terminated. */
1366 thread_set_state_terminated(t);
1368 /* Notify all threads waiting on this thread. These are joining
1371 o = (java_handle_t *) object;
1373 /* XXX Care about exceptions? */
1374 (void) lock_monitor_enter(o);
1376 lock_notify_all_object(o);
1378 /* XXX Care about exceptions? */
1379 (void) lock_monitor_exit(o);
1381 /* Enter the join-mutex before calling thread_free, so
1382 threads_join_all_threads gets the correct number of non-daemon
1385 threads_mutex_join_lock();
1387 /* Free the internal thread data-structure. */
1391 /* Signal that this thread has finished and leave the mutex. */
1393 pthread_cond_signal(&cond_join);
1394 threads_mutex_join_unlock();
1400 #if defined(ENABLE_GC_CACAO)
1402 /* threads_suspend_thread ******************************************************
1404 Suspend the passed thread. Execution stops until the thread
1405 is explicitly resumend again.
1408 reason.....Reason for suspending this thread.
1410 *******************************************************************************/
1412 bool threads_suspend_thread(threadobject *thread, s4 reason)
1414 /* acquire the suspendmutex */
1415 mutex_lock(&(thread->suspendmutex));
1417 if (thread->suspended) {
1418 mutex_unlock(&(thread->suspendmutex));
1422 /* set the reason for the suspension */
1423 thread->suspend_reason = reason;
1425 /* send the suspend signal to the thread */
1426 assert(thread != THREADOBJECT);
1427 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1428 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1431 /* REMEMBER: do not release the suspendmutex, this is done
1432 by the thread itself in threads_suspend_ack(). */
1438 /* threads_suspend_ack *********************************************************
1440 Acknowledges the suspension of the current thread.
1443 pc.....The PC where the thread suspended its execution.
1444 sp.....The SP before the thread suspended its execution.
1446 *******************************************************************************/
1448 void threads_suspend_ack(u1* pc, u1* sp)
1450 threadobject *thread;
1452 thread = THREADOBJECT;
1454 assert(thread->suspend_reason != 0);
1456 /* TODO: remember dump memory size */
1458 /* inform the GC about the suspension */
1459 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1461 /* check if the GC wants to leave the thread running */
1462 if (!gc_suspend(thread, pc, sp)) {
1464 /* REMEMBER: we do not unlock the suspendmutex because the thread
1465 will suspend itself again at a later time */
1471 /* mark this thread as suspended and remember the PC */
1473 thread->suspended = true;
1475 /* if we are stopping the world, we should send a global ack */
1476 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1477 threads_sem_post(&suspend_ack);
1480 DEBUGTHREADS("suspending", thread);
1482 /* release the suspension mutex and wait till we are resumed */
1483 pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
1485 DEBUGTHREADS("resuming", thread);
1487 /* if we are stopping the world, we should send a global ack */
1488 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1489 threads_sem_post(&suspend_ack);
1492 /* TODO: free dump memory */
1494 /* release the suspendmutex */
1495 mutex_unlock(&(thread->suspendmutex));
1499 /* threads_resume_thread *******************************************************
1501 Resumes the execution of the passed thread.
1503 *******************************************************************************/
1505 bool threads_resume_thread(threadobject *thread)
1507 /* acquire the suspendmutex */
1508 mutex_lock(&(thread->suspendmutex));
1510 if (!thread->suspended) {
1511 mutex_unlock(&(thread->suspendmutex));
1515 thread->suspended = false;
1517 /* tell everyone that the thread should resume */
1518 assert(thread != THREADOBJECT);
1519 pthread_cond_broadcast(&(thread->suspendcond));
1521 /* release the suspendmutex */
1522 mutex_unlock(&(thread->suspendmutex));
1529 /* threads_join_all_threads ****************************************************
1531 Join all non-daemon threads.
1533 *******************************************************************************/
1535 void threads_join_all_threads(void)
1539 /* get current thread */
1543 /* This thread is waiting for all non-daemon threads to exit. */
1545 thread_set_state_waiting(t);
1547 /* enter join mutex */
1549 threads_mutex_join_lock();
1551 /* Wait for condition as long as we have non-daemon threads. We
1552 compare against 1 because the current (main thread) is also a
1553 non-daemon thread. */
1555 while (threadlist_get_non_daemons() > 1)
1556 pthread_cond_wait(&cond_join, &mutex_join);
1558 /* leave join mutex */
1560 threads_mutex_join_unlock();
1564 /* threads_timespec_earlier ****************************************************
1566 Return true if timespec tv1 is earlier than timespec tv2.
1569 tv1..........first timespec
1570 tv2..........second timespec
1573 true, if the first timespec is earlier
1575 *******************************************************************************/
1577 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1578 const struct timespec *tv2)
1580 return (tv1->tv_sec < tv2->tv_sec)
1582 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1586 /* threads_current_time_is_earlier_than ****************************************
1588 Check if the current time is earlier than the given timespec.
1591 tv...........the timespec to compare against
1594 true, if the current time is earlier
1596 *******************************************************************************/
1598 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1600 struct timeval tvnow;
1601 struct timespec tsnow;
1603 /* get current time */
1605 if (gettimeofday(&tvnow, NULL) != 0)
1606 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1608 /* convert it to a timespec */
1610 tsnow.tv_sec = tvnow.tv_sec;
1611 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1613 /* compare current time with the given timespec */
1615 return threads_timespec_earlier(&tsnow, tv);
1619 /* threads_wait_with_timeout ***************************************************
1621 Wait until the given point in time on a monitor until either
1622 we are notified, we are interrupted, or the time is up.
1625 t............the current thread
1626 wakeupTime...absolute (latest) wakeup time
1627 If both tv_sec and tv_nsec are zero, this function
1628 waits for an unlimited amount of time.
1630 *******************************************************************************/
1632 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
1634 /* acquire the waitmutex */
1636 mutex_lock(&t->waitmutex);
1638 /* wait on waitcond */
1640 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1642 while (!t->interrupted && !t->signaled
1643 && threads_current_time_is_earlier_than(wakeupTime))
1645 thread_set_state_timed_waiting(t);
1647 pthread_cond_timedwait(&t->waitcond, &t->waitmutex,
1650 thread_set_state_runnable(t);
1655 while (!t->interrupted && !t->signaled) {
1656 thread_set_state_waiting(t);
1658 pthread_cond_wait(&t->waitcond, &t->waitmutex);
1660 thread_set_state_runnable(t);
1664 /* release the waitmutex */
1666 mutex_unlock(&t->waitmutex);
1670 /* threads_wait_with_timeout_relative ******************************************
1672 Wait for the given maximum amount of time on a monitor until either
1673 we are notified, we are interrupted, or the time is up.
1676 t............the current thread
1677 millis.......milliseconds to wait
1678 nanos........nanoseconds to wait
1680 *******************************************************************************/
1682 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1685 struct timespec wakeupTime;
1687 /* calculate the the (latest) wakeup time */
1689 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1693 threads_wait_with_timeout(thread, &wakeupTime);
1697 /* threads_calc_absolute_time **************************************************
1699 Calculate the absolute point in time a given number of ms and ns from now.
1702 millis............milliseconds from now
1703 nanos.............nanoseconds from now
1706 *tm...............receives the timespec of the absolute point in time
1708 *******************************************************************************/
1710 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1712 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1715 gettimeofday(&tv, NULL);
1716 tv.tv_sec += millis / 1000;
1718 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1719 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1720 tm->tv_nsec = nsec % 1000000000;
1729 /* threads_thread_interrupt ****************************************************
1731 Interrupt the given thread.
1733 The thread gets the "waitcond" signal and
1734 its interrupted flag is set to true.
1737 thread............the thread to interrupt
1739 *******************************************************************************/
1741 void threads_thread_interrupt(threadobject *thread)
1743 #if defined(__LINUX__) && defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1744 /* See openjdk/jdk/src/solaris/native/java/net/linux_close.c, "sigWakeup" */
1745 int sig = (__SIGRTMAX - 2);
1749 /* Signal the thread a "waitcond" and tell it that it has been
1752 mutex_lock(&thread->waitmutex);
1754 DEBUGTHREADS("interrupted", thread);
1756 /* Interrupt blocking system call using a signal. */
1758 pthread_kill(thread->tid, sig);
1760 pthread_cond_signal(&thread->waitcond);
1762 thread->interrupted = true;
1764 mutex_unlock(&thread->waitmutex);
1768 /* threads_sleep ***************************************************************
1770 Sleep the current thread for the specified amount of time.
1772 *******************************************************************************/
1774 void threads_sleep(int64_t millis, int32_t nanos)
1777 struct timespec wakeupTime;
1781 /* exceptions_throw_illegalargumentexception("timeout value is negative"); */
1782 exceptions_throw_illegalargumentexception();
1786 t = thread_get_current();
1788 if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1789 /* Clear interrupted flag (Mauve test:
1790 gnu/testlet/java/lang/Thread/interrupt). */
1792 thread_set_interrupted(t, false);
1794 /* exceptions_throw_interruptedexception("sleep interrupted"); */
1795 exceptions_throw_interruptedexception();
1799 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1801 threads_wait_with_timeout(t, &wakeupTime);
1803 interrupted = thread_is_interrupted(t);
1806 thread_set_interrupted(t, false);
1808 /* An other exception could have been thrown
1809 (e.g. ThreadDeathException). */
1811 if (!exceptions_get_exception())
1812 exceptions_throw_interruptedexception();
1817 /* threads_yield ***************************************************************
1819 Yield to the scheduler.
1821 *******************************************************************************/
1823 void threads_yield(void)
1830 * These are local overrides for various environment variables in Emacs.
1831 * Please do not remove this and leave it at the end of the file, where
1832 * Emacs will automagically detect them.
1833 * ---------------------------------------------------------------------
1836 * indent-tabs-mode: t
1840 * vim:noexpandtab:sw=4:ts=4: