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 #if !defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
47 # include "machine-instr.h"
49 # include "threads/posix/generic-primitives.h"
52 #include "mm/gc-common.h"
53 #include "mm/memory.h"
55 #if defined(ENABLE_GC_CACAO)
56 # include "mm/cacao-gc/gc.h"
59 #include "native/jni.h"
60 #include "native/llni.h"
61 #include "native/native.h"
63 #include "native/include/java_lang_Object.h"
64 #include "native/include/java_lang_String.h"
65 #include "native/include/java_lang_Throwable.h"
66 #include "native/include/java_lang_Thread.h"
68 #if defined(ENABLE_JAVASE)
69 # include "native/include/java_lang_ThreadGroup.h"
72 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
73 # include "native/include/java_lang_VMThread.h"
76 #include "threads/lock-common.h"
77 #include "threads/mutex.h"
78 #include "threads/threadlist.h"
79 #include "threads/thread.h"
81 #include "toolbox/logging.h"
83 #include "vm/builtin.h"
84 #include "vm/exceptions.h"
85 #include "vm/global.h"
86 #include "vm/stringlocal.h"
89 #include "vm/jit/asmpart.h"
91 #include "vmcore/options.h"
93 #if defined(ENABLE_STATISTICS)
94 # include "vmcore/statistics.h"
97 #if !defined(__DARWIN__)
98 # include <semaphore.h>
100 # if defined(__LINUX__)
101 # define GC_LINUX_THREADS
102 # elif defined(__IRIX__)
103 # define GC_IRIX_THREADS
104 # elif defined(__DARWIN__)
105 # define GC_DARWIN_THREADS
107 # if defined(ENABLE_GC_BOEHM)
108 # include "mm/boehm-gc/include/gc.h"
111 #if defined(ENABLE_JVMTI)
112 #include "native/jvmti/cacaodbg.h"
115 #if defined(__DARWIN__)
116 /* Darwin has no working semaphore implementation. This one is taken
120 This is a very simple semaphore implementation for darwin. It
121 is implemented in terms of pthreads calls so it isn't async signal
122 safe. This isn't a problem because signals aren't used to
123 suspend threads on darwin.
126 static int sem_init(sem_t *sem, int pshared, int value)
133 mutex_init(&sem->mutex);
135 if (pthread_cond_init(&sem->cond, NULL) < 0)
141 static int sem_post(sem_t *sem)
143 mutex_lock(&sem->mutex);
147 if (pthread_cond_signal(&sem->cond) < 0) {
148 mutex_unlock(&sem->mutex);
152 mutex_unlock(&sem->mutex);
157 static int sem_wait(sem_t *sem)
159 mutex_lock(&sem->mutex);
161 while (sem->value == 0) {
162 pthread_cond_wait(&sem->cond, &sem->mutex);
167 mutex_unlock(&sem->mutex);
172 static int sem_destroy(sem_t *sem)
174 if (pthread_cond_destroy(&sem->cond) < 0)
177 mutex_destroy(&sem->mutex);
181 #endif /* defined(__DARWIN__) */
184 /* internally used constants **************************************************/
186 /* CAUTION: Do not change these values. Boehm GC code depends on them. */
187 #define STOPWORLD_FROM_GC 1
188 #define STOPWORLD_FROM_CLASS_NUMBERING 2
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_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
212 /******************************************************************************/
213 /* GLOBAL VARIABLES */
214 /******************************************************************************/
216 /* the thread object of the current thread */
217 /* This is either a thread-local variable defined with __thread, or */
218 /* a thread-specific value stored with key threads_current_threadobject_key. */
219 #if defined(HAVE___THREAD)
220 __thread threadobject *thread_current;
222 pthread_key_t thread_current_key;
225 /* global mutex for stop-the-world */
226 static mutex_t stopworldlock;
228 #if defined(ENABLE_GC_CACAO)
229 /* global mutex for the GC */
230 static mutex_t mutex_gc;
233 /* global mutex and condition for joining threads on exit */
234 static mutex_t mutex_join;
235 static pthread_cond_t cond_join;
237 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
239 static volatile int stopworldwhere;
241 #if defined(ENABLE_GC_CACAO)
243 /* semaphore used for acknowleding thread suspension */
244 static sem_t suspend_ack;
245 #if defined(__IRIX__)
246 static mutex_t suspend_ack_lock = MUTEX_INITIALIZER;
247 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
250 #endif /* ENABLE_GC_CACAO */
252 /* mutexes used by the fake atomic instructions */
253 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
254 mutex_t _cas_lock = MUTEX_INITIALIZER;
255 mutex_t _mb_lock = MUTEX_INITIALIZER;
259 /* threads_sem_init ************************************************************
261 Initialize a semaphore. Checks against errors and interruptions.
264 sem..............the semaphore to initialize
265 shared...........true if this semaphore will be shared between processes
266 value............the initial value for the semaphore
268 *******************************************************************************/
270 void threads_sem_init(sem_t *sem, bool shared, int value)
277 r = sem_init(sem, shared, value);
280 } while (errno == EINTR);
282 vm_abort("sem_init failed: %s", strerror(errno));
286 /* threads_sem_wait ************************************************************
288 Wait for a semaphore, non-interruptible.
290 IMPORTANT: Always use this function instead of `sem_wait` directly, as
291 `sem_wait` may be interrupted by signals!
294 sem..............the semaphore to wait on
296 *******************************************************************************/
298 void threads_sem_wait(sem_t *sem)
308 } while (errno == EINTR);
310 vm_abort("sem_wait failed: %s", strerror(errno));
314 /* threads_sem_post ************************************************************
316 Increase the count of a semaphore. Checks for errors.
319 sem..............the semaphore to increase the count of
321 *******************************************************************************/
323 void threads_sem_post(sem_t *sem)
329 /* unlike sem_wait, sem_post is not interruptible */
335 vm_abort("sem_post failed: %s", strerror(errno));
339 /* lock_stopworld **************************************************************
341 Enter the stopworld lock, specifying why the world shall be stopped.
344 where........ STOPWORLD_FROM_GC (1) from within GC
345 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
347 ******************************************************************************/
349 void lock_stopworld(int where)
351 mutex_lock(&stopworldlock);
352 /* stopworldwhere = where; */
356 /* unlock_stopworld ************************************************************
358 Release the stopworld lock.
360 ******************************************************************************/
362 void unlock_stopworld(void)
364 /* stopworldwhere = 0; */
365 mutex_unlock(&stopworldlock);
368 /* XXX We disable that whole bunch of code until we have the exact-GC
369 running. Some of it may only be needed by the old Boehm-based
370 suspension handling. */
374 #if !defined(__DARWIN__)
375 /* Caller must hold threadlistlock */
376 static s4 threads_cast_sendsignals(s4 sig)
384 /* iterate over all started threads */
388 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
389 /* don't send the signal to ourself */
394 /* don't send the signal to NEW threads (because they are not
395 completely initialized) */
397 if (t->state == THREAD_STATE_NEW)
400 /* send the signal */
402 pthread_kill(t->tid, sig);
404 /* increase threads count */
414 static void threads_cast_darwinstop(void)
416 threadobject *tobj = mainthreadobj;
417 threadobject *self = THREADOBJECT;
422 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
423 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
424 #if defined(__I386__)
425 i386_thread_state_t thread_state;
427 ppc_thread_state_t thread_state;
429 mach_port_t thread = tobj->mach_thread;
432 r = thread_suspend(thread);
434 if (r != KERN_SUCCESS)
435 vm_abort("thread_suspend failed");
437 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
438 &thread_state_count);
440 if (r != KERN_SUCCESS)
441 vm_abort("thread_get_state failed");
443 md_critical_section_restart((ucontext_t *) &thread_state);
445 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
448 if (r != KERN_SUCCESS)
449 vm_abort("thread_set_state failed");
453 } while (tobj != mainthreadobj);
456 static void threads_cast_darwinresume(void)
458 threadobject *tobj = mainthreadobj;
459 threadobject *self = THREADOBJECT;
464 mach_port_t thread = tobj->mach_thread;
467 r = thread_resume(thread);
469 if (r != KERN_SUCCESS)
470 vm_abort("thread_resume failed");
474 } while (tobj != mainthreadobj);
479 #if defined(__IRIX__)
480 static void threads_cast_irixresume(void)
482 mutex_lock(&suspend_ack_lock);
483 pthread_cond_broadcast(&suspend_cond);
484 mutex_unlock(&suspend_ack_lock);
488 #if defined(ENABLE_GC_BOEHM) && !defined(__DARWIN__)
489 static void threads_sigsuspend_handler(ucontext_t *_uc)
494 /* XXX TWISTI: this is just a quick hack */
495 #if defined(ENABLE_JIT)
496 md_critical_section_restart(_uc);
499 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
500 (not POSIX async-safe). */
501 #if defined(__IRIX__)
502 mutex_lock(&suspend_ack_lock);
503 threads_sem_post(&suspend_ack);
504 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
505 mutex_unlock(&suspend_ack_lock);
506 #elif defined(__CYGWIN__)
513 sigdelset(&sigs, sig);
520 /* threads_stopworld ***********************************************************
522 Stops the world from turning. All threads except the calling one
523 are suspended. The function returns as soon as all threads have
524 acknowledged their suspension.
526 *******************************************************************************/
528 void threads_stopworld(void)
530 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
537 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
539 /* lock the threads lists */
543 #if defined(__DARWIN__)
544 /*threads_cast_darwinstop();*/
546 #elif defined(__CYGWIN__)
552 DEBUGTHREADS("stops World", self);
556 /* suspend all running threads */
557 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
558 /* don't send the signal to ourself */
563 /* don't send the signal to NEW threads (because they are not
564 completely initialized) */
566 if (t->state == THREAD_STATE_NEW)
569 /* send the signal */
571 result = threads_suspend_thread(t, SUSPEND_REASON_STOPWORLD);
574 /* increase threads count */
579 /* wait for all threads signaled to suspend */
580 for (i = 0; i < count; i++)
581 threads_sem_wait(&suspend_ack);
584 /* ATTENTION: Don't unlock the threads-lists here so that
585 non-signaled NEW threads can't change their state and execute
590 /* threads_startworld **********************************************************
592 Starts the world again after it has previously been stopped.
594 *******************************************************************************/
596 void threads_startworld(void)
598 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
605 #if defined(__DARWIN__)
606 /*threads_cast_darwinresume();*/
608 #elif defined(__IRIX__)
609 threads_cast_irixresume();
610 #elif defined(__CYGWIN__)
616 DEBUGTHREADS("starts World", self);
620 /* resume all thread we haltet */
621 for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
622 /* don't send the signal to ourself */
627 /* don't send the signal to NEW threads (because they are not
628 completely initialized) */
630 if (t->state == THREAD_STATE_NEW)
633 /* send the signal */
635 result = threads_resume_thread(t);
638 /* increase threads count */
643 /* wait for all threads signaled to suspend */
644 for (i = 0; i < count; i++)
645 threads_sem_wait(&suspend_ack);
649 /* unlock the threads lists */
659 /* threads_impl_thread_init ****************************************************
661 Initialize OS-level locking constructs in threadobject.
664 t....the threadobject
666 *******************************************************************************/
668 void threads_impl_thread_init(threadobject *t)
672 /* initialize the mutex and the condition */
674 mutex_init(&t->flc_lock);
676 result = pthread_cond_init(&t->flc_cond, NULL);
678 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
680 mutex_init(&(t->waitmutex));
682 result = pthread_cond_init(&(t->waitcond), NULL);
684 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
686 mutex_init(&(t->suspendmutex));
688 result = pthread_cond_init(&(t->suspendcond), NULL);
690 vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
693 /* threads_impl_thread_clear ***************************************************
695 Clears all fields in threadobject the way an MZERO would have
696 done. MZERO cannot be used anymore because it would mess up the
700 t....the threadobject
702 *******************************************************************************/
704 void threads_impl_thread_clear(threadobject *t)
716 #if defined(__DARWIN__)
720 t->interrupted = false;
724 t->suspended = false;
725 t->suspend_reason = 0;
729 t->_exceptionptr = NULL;
730 t->_stackframeinfo = NULL;
731 t->_localref_table = NULL;
733 #if defined(ENABLE_INTRP)
734 t->_global_sp = NULL;
737 #if defined(ENABLE_GC_CACAO)
738 t->gc_critical = false;
744 MZERO(&t->dumpinfo, dumpinfo_t, 1);
747 /* threads_impl_thread_reuse ***************************************************
749 Resets some implementation fields in threadobject. This was
750 previously done in threads_impl_thread_new.
753 t....the threadobject
755 *******************************************************************************/
757 void threads_impl_thread_reuse(threadobject *t)
759 /* get the pthread id */
761 t->tid = pthread_self();
763 #if defined(ENABLE_DEBUG_FILTER)
764 /* Initialize filter counters */
765 t->filterverbosecallctr[0] = 0;
766 t->filterverbosecallctr[1] = 0;
770 t->tracejavacallindent = 0;
771 t->tracejavacallcount = 0;
778 /* not really needed */
779 t->flc_object = NULL;
783 /* threads_impl_thread_free ****************************************************
785 Cleanup thread stuff.
788 t....the threadobject
790 *******************************************************************************/
794 void threads_impl_thread_free(threadobject *t)
798 /* Destroy the mutex and the condition. */
800 mutex_destroy(&(t->flc_lock));
802 result = pthread_cond_destroy(&(t->flc_cond));
805 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
807 mutex_destroy(&(t->waitmutex));
809 result = pthread_cond_destroy(&(t->waitcond));
812 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
814 mutex_destroy(&(t->suspendmutex));
816 result = pthread_cond_destroy(&(t->suspendcond));
819 vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
824 /* threads_impl_preinit ********************************************************
826 Do some early initialization of stuff required.
828 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
829 is called AFTER this function!
831 *******************************************************************************/
833 void threads_impl_preinit(void)
837 mutex_init(&stopworldlock);
839 /* initialize exit mutex and condition (on exit we join all
842 mutex_init(&mutex_join);
844 result = pthread_cond_init(&cond_join, NULL);
846 vm_abort_errnum(result, "threads_impl_preinit: pthread_cond_init failed");
848 #if defined(ENABLE_GC_CACAO)
849 /* initialize the GC mutex & suspend semaphore */
851 mutex_init(&mutex_gc);
852 threads_sem_init(&suspend_ack, 0, 0);
855 #if !defined(HAVE___THREAD)
856 result = pthread_key_create(&thread_current_key, NULL);
858 vm_abort_errnum(result, "threads_impl_preinit: pthread_key_create failed");
863 /* threads_mutex_gc_lock *******************************************************
865 Enter the global GC mutex.
867 *******************************************************************************/
869 #if defined(ENABLE_GC_CACAO)
870 void threads_mutex_gc_lock(void)
872 mutex_lock(&mutex_gc);
877 /* threads_mutex_gc_unlock *****************************************************
879 Leave the global GC mutex.
881 *******************************************************************************/
883 #if defined(ENABLE_GC_CACAO)
884 void threads_mutex_gc_unlock(void)
886 mutex_unlock(&mutex_gc);
890 /* threads_mutex_join_lock *****************************************************
892 Enter the join mutex.
894 *******************************************************************************/
896 void threads_mutex_join_lock(void)
898 mutex_lock(&mutex_join);
902 /* threads_mutex_join_unlock ***************************************************
904 Leave the join mutex.
906 *******************************************************************************/
908 void threads_mutex_join_unlock(void)
910 mutex_unlock(&mutex_join);
914 /* threads_impl_init ***********************************************************
916 Initializes the implementation specific bits.
918 *******************************************************************************/
920 void threads_impl_init(void)
925 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
927 /* Initialize the thread attribute object. */
929 result = pthread_attr_init(&attr);
932 vm_abort_errnum(result, "threads_impl_init: pthread_attr_init failed");
934 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
937 vm_abort_errnum(result, "threads_impl_init: pthread_attr_setdetachstate failed");
941 /* threads_startup_thread ******************************************************
943 Thread startup function called by pthread_create.
945 Thread which have a startup.function != NULL are marked as internal
946 threads. All other threads are threated as normal Java threads.
948 NOTE: This function is not called directly by pthread_create. The Boehm GC
949 inserts its own GC_start_routine in between, which then calls
953 arg..........the argument passed to pthread_create, ie. a pointer to
954 a startupinfo struct. CAUTION: When the `psem` semaphore
955 is posted, the startupinfo struct becomes invalid! (It
956 is allocated on the stack of threads_start_thread.)
958 ******************************************************************************/
960 static void *threads_startup_thread(void *arg)
962 startupinfo *startup;
964 java_lang_Thread *object;
965 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
966 java_lang_VMThread *vmt;
972 functionptr function;
974 #if defined(ENABLE_INTRP)
975 u1 *intrp_thread_stack;
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 /* get the java.lang.Thread object for this thread */
1012 object = (java_lang_Thread *) thread_get_object(t);
1014 /* set our priority */
1016 threads_set_thread_priority(t->tid, LLNI_field_direct(object, priority));
1018 /* Thread is completely initialized. */
1020 thread_set_state_runnable(t);
1022 /* tell threads_startup_thread that we registered ourselves */
1023 /* CAUTION: *startup becomes invalid with this! */
1026 threads_sem_post(psem);
1028 #if defined(ENABLE_INTRP)
1029 /* set interpreter stack */
1032 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1035 #if defined(ENABLE_JVMTI)
1036 /* fire thread start event */
1039 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1042 DEBUGTHREADS("starting", t);
1044 /* find and run the Thread.run()V method if no other function was passed */
1046 if (function == NULL) {
1047 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1048 /* We need to start the run method of
1049 java.lang.VMThread. Since this is a final class, we can use
1050 the class object directly. */
1052 c = class_java_lang_VMThread;
1053 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1054 LLNI_class_get(object, c);
1056 # error unknown classpath configuration
1059 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1062 vm_abort("threads_startup_thread: run() method not found in class");
1064 /* set ThreadMXBean variables */
1066 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1067 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1069 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1070 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1071 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1072 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1074 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1075 /* we need to start the run method of java.lang.VMThread */
1077 LLNI_field_get_ref(object, vmThread, vmt);
1078 o = (java_handle_t *) vmt;
1080 #elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK) || defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
1081 o = (java_handle_t *) object;
1083 # error unknown classpath configuration
1086 /* Run the thread. */
1088 (void) vm_call_method(m, o);
1091 /* set ThreadMXBean variables */
1093 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1094 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1096 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1097 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1098 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1099 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1101 /* call passed function, e.g. finalizer_thread */
1106 DEBUGTHREADS("stopping", t);
1108 #if defined(ENABLE_JVMTI)
1109 /* fire thread end event */
1112 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1115 /* We ignore the return value. */
1117 (void) threads_detach_thread(t);
1119 /* set ThreadMXBean variables */
1121 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1127 /* threads_impl_thread_start ***************************************************
1129 Start a thread in the JVM. Both (vm internal and java) thread
1133 thread....the thread object
1134 f.........function to run in the new thread. NULL means that the
1135 "run" method of the object `t` should be called
1137 ******************************************************************************/
1139 void threads_impl_thread_start(threadobject *thread, functionptr f)
1143 pthread_attr_t attr;
1144 startupinfo startup;
1147 /* fill startupinfo structure passed by pthread_create to
1148 * threads_startup_thread */
1150 startup.thread = thread;
1151 startup.function = f; /* maybe we don't call Thread.run()V */
1152 startup.psem = &sem;
1153 startup.psem_first = &sem_first;
1155 threads_sem_init(&sem, 0, 0);
1156 threads_sem_init(&sem_first, 0, 0);
1158 /* Initialize thread attributes. */
1160 result = pthread_attr_init(&attr);
1163 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_init failed");
1165 result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1168 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setdetachstate failed");
1170 /* initialize thread stacksize */
1172 result = pthread_attr_setstacksize(&attr, opt_stacksize);
1175 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_setstacksize failed");
1177 /* create the thread */
1179 result = pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup);
1182 vm_abort_errnum(result, "threads_impl_thread_start: pthread_create failed");
1184 /* destroy the thread attributes */
1186 result = pthread_attr_destroy(&attr);
1189 vm_abort_errnum(result, "threads_impl_thread_start: pthread_attr_destroy failed");
1191 /* signal that pthread_create has returned, so thread->tid is valid */
1193 threads_sem_post(&sem_first);
1195 /* wait here until the thread has entered itself into the thread list */
1197 threads_sem_wait(&sem);
1202 sem_destroy(&sem_first);
1206 /* threads_set_thread_priority *************************************************
1208 Set the priority of the given thread.
1211 tid..........thread id
1212 priority.....priority to set
1214 ******************************************************************************/
1216 void threads_set_thread_priority(pthread_t tid, int priority)
1218 struct sched_param schedp;
1221 pthread_getschedparam(tid, &policy, &schedp);
1222 schedp.sched_priority = priority;
1223 pthread_setschedparam(tid, policy, &schedp);
1227 /* threads_detach_thread *******************************************************
1229 Detaches the passed thread from the VM. Used in JNI.
1231 *******************************************************************************/
1233 bool threads_detach_thread(threadobject *t)
1236 java_lang_Thread *object;
1238 #if defined(ENABLE_JAVASE)
1239 java_lang_ThreadGroup *group;
1246 /* If the given thread has already been detached, this operation
1249 result = thread_is_attached(t);
1251 if (result == false)
1254 DEBUGTHREADS("detaching", t);
1256 object = (java_lang_Thread *) thread_get_object(t);
1258 #if defined(ENABLE_JAVASE)
1259 LLNI_field_get_ref(object, group, group);
1261 /* If there's an uncaught exception, call uncaughtException on the
1262 thread's exception handler, or the thread's group if this is
1265 e = exceptions_get_and_clear_exception();
1268 /* We use the type void* for handler here, as it's not trivial
1269 to build the java_lang_Thread_UncaughtExceptionHandler
1270 header file with cacaoh. */
1272 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1273 LLNI_field_get_ref(object, exceptionHandler, handler);
1274 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1275 LLNI_field_get_ref(object, uncaughtExceptionHandler, handler);
1278 if (handler != NULL) {
1279 LLNI_class_get(handler, c);
1280 o = (java_handle_t *) handler;
1283 LLNI_class_get(group, c);
1284 o = (java_handle_t *) group;
1287 m = class_resolveclassmethod(c,
1288 utf_uncaughtException,
1289 utf_java_lang_Thread_java_lang_Throwable__V,
1296 (void) vm_call_method(m, o, object, e);
1298 if (exceptions_get_exception())
1302 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1304 /* Remove thread from the thread group. */
1306 if (group != NULL) {
1307 LLNI_class_get(group, c);
1309 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
1310 m = class_resolveclassmethod(c,
1312 utf_java_lang_Thread__V,
1313 class_java_lang_ThreadGroup,
1315 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1316 m = class_resolveclassmethod(c,
1318 utf_java_lang_Thread__V,
1319 class_java_lang_ThreadGroup,
1322 # error unknown classpath configuration
1328 o = (java_handle_t *) group;
1330 (void) vm_call_method(m, o, object);
1332 if (exceptions_get_exception())
1335 /* Reset the threadgroup in the Java thread object (Mauve
1336 test: gnu/testlet/java/lang/Thread/getThreadGroup). */
1338 LLNI_field_set_ref(object, group, NULL);
1342 /* Thread has terminated. */
1344 thread_set_state_terminated(t);
1346 /* Notify all threads waiting on this thread. These are joining
1349 o = (java_handle_t *) object;
1351 /* XXX Care about exceptions? */
1352 (void) lock_monitor_enter(o);
1354 lock_notify_all_object(o);
1356 /* XXX Care about exceptions? */
1357 (void) lock_monitor_exit(o);
1359 /* Enter the join-mutex before calling thread_free, so
1360 threads_join_all_threads gets the correct number of non-daemon
1363 threads_mutex_join_lock();
1365 /* Free the internal thread data-structure. */
1369 /* Signal that this thread has finished and leave the mutex. */
1371 pthread_cond_signal(&cond_join);
1372 threads_mutex_join_unlock();
1378 #if defined(ENABLE_GC_CACAO)
1380 /* threads_suspend_thread ******************************************************
1382 Suspend the passed thread. Execution stops until the thread
1383 is explicitly resumend again.
1386 reason.....Reason for suspending this thread.
1388 *******************************************************************************/
1390 bool threads_suspend_thread(threadobject *thread, s4 reason)
1392 /* acquire the suspendmutex */
1393 mutex_lock(&(thread->suspendmutex));
1395 if (thread->suspended) {
1396 mutex_unlock(&(thread->suspendmutex));
1400 /* set the reason for the suspension */
1401 thread->suspend_reason = reason;
1403 /* send the suspend signal to the thread */
1404 assert(thread != THREADOBJECT);
1405 if (pthread_kill(thread->tid, SIGUSR1) != 0)
1406 vm_abort("threads_suspend_thread: pthread_kill failed: %s",
1409 /* REMEMBER: do not release the suspendmutex, this is done
1410 by the thread itself in threads_suspend_ack(). */
1416 /* threads_suspend_ack *********************************************************
1418 Acknowledges the suspension of the current thread.
1421 pc.....The PC where the thread suspended its execution.
1422 sp.....The SP before the thread suspended its execution.
1424 *******************************************************************************/
1426 void threads_suspend_ack(u1* pc, u1* sp)
1428 threadobject *thread;
1430 thread = THREADOBJECT;
1432 assert(thread->suspend_reason != 0);
1434 /* TODO: remember dump memory size */
1436 /* inform the GC about the suspension */
1437 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD && gc_pending) {
1439 /* check if the GC wants to leave the thread running */
1440 if (!gc_suspend(thread, pc, sp)) {
1442 /* REMEMBER: we do not unlock the suspendmutex because the thread
1443 will suspend itself again at a later time */
1449 /* mark this thread as suspended and remember the PC */
1451 thread->suspended = true;
1453 /* if we are stopping the world, we should send a global ack */
1454 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1455 threads_sem_post(&suspend_ack);
1458 DEBUGTHREADS("suspending", thread);
1460 /* release the suspension mutex and wait till we are resumed */
1461 pthread_cond_wait(&(thread->suspendcond), &(thread->suspendmutex));
1463 DEBUGTHREADS("resuming", thread);
1465 /* if we are stopping the world, we should send a global ack */
1466 if (thread->suspend_reason == SUSPEND_REASON_STOPWORLD) {
1467 threads_sem_post(&suspend_ack);
1470 /* TODO: free dump memory */
1472 /* release the suspendmutex */
1473 mutex_unlock(&(thread->suspendmutex));
1477 /* threads_resume_thread *******************************************************
1479 Resumes the execution of the passed thread.
1481 *******************************************************************************/
1483 bool threads_resume_thread(threadobject *thread)
1485 /* acquire the suspendmutex */
1486 mutex_lock(&(thread->suspendmutex));
1488 if (!thread->suspended) {
1489 mutex_unlock(&(thread->suspendmutex));
1493 thread->suspended = false;
1495 /* tell everyone that the thread should resume */
1496 assert(thread != THREADOBJECT);
1497 pthread_cond_broadcast(&(thread->suspendcond));
1499 /* release the suspendmutex */
1500 mutex_unlock(&(thread->suspendmutex));
1507 /* threads_join_all_threads ****************************************************
1509 Join all non-daemon threads.
1511 *******************************************************************************/
1513 void threads_join_all_threads(void)
1517 /* get current thread */
1521 /* This thread is waiting for all non-daemon threads to exit. */
1523 thread_set_state_waiting(t);
1525 /* enter join mutex */
1527 threads_mutex_join_lock();
1529 /* Wait for condition as long as we have non-daemon threads. We
1530 compare against 1 because the current (main thread) is also a
1531 non-daemon thread. */
1533 while (threadlist_get_non_daemons() > 1)
1534 pthread_cond_wait(&cond_join, &mutex_join);
1536 /* leave join mutex */
1538 threads_mutex_join_unlock();
1542 /* threads_timespec_earlier ****************************************************
1544 Return true if timespec tv1 is earlier than timespec tv2.
1547 tv1..........first timespec
1548 tv2..........second timespec
1551 true, if the first timespec is earlier
1553 *******************************************************************************/
1555 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1556 const struct timespec *tv2)
1558 return (tv1->tv_sec < tv2->tv_sec)
1560 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1564 /* threads_current_time_is_earlier_than ****************************************
1566 Check if the current time is earlier than the given timespec.
1569 tv...........the timespec to compare against
1572 true, if the current time is earlier
1574 *******************************************************************************/
1576 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1578 struct timeval tvnow;
1579 struct timespec tsnow;
1581 /* get current time */
1583 if (gettimeofday(&tvnow, NULL) != 0)
1584 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1586 /* convert it to a timespec */
1588 tsnow.tv_sec = tvnow.tv_sec;
1589 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1591 /* compare current time with the given timespec */
1593 return threads_timespec_earlier(&tsnow, tv);
1597 /* threads_wait_with_timeout ***************************************************
1599 Wait until the given point in time on a monitor until either
1600 we are notified, we are interrupted, or the time is up.
1603 t............the current thread
1604 wakeupTime...absolute (latest) wakeup time
1605 If both tv_sec and tv_nsec are zero, this function
1606 waits for an unlimited amount of time.
1608 *******************************************************************************/
1610 static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTime)
1612 /* acquire the waitmutex */
1614 mutex_lock(&t->waitmutex);
1616 /* mark us as sleeping */
1620 /* wait on waitcond */
1622 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1624 while (!t->interrupted && !t->signaled
1625 && threads_current_time_is_earlier_than(wakeupTime))
1627 thread_set_state_timed_waiting(t);
1629 pthread_cond_timedwait(&t->waitcond, &t->waitmutex,
1632 thread_set_state_runnable(t);
1637 while (!t->interrupted && !t->signaled) {
1638 thread_set_state_waiting(t);
1640 pthread_cond_wait(&t->waitcond, &t->waitmutex);
1642 thread_set_state_runnable(t);
1646 t->sleeping = false;
1648 /* release the waitmutex */
1650 mutex_unlock(&t->waitmutex);
1654 /* threads_wait_with_timeout_relative ******************************************
1656 Wait for the given maximum amount of time on a monitor until either
1657 we are notified, we are interrupted, or the time is up.
1660 t............the current thread
1661 millis.......milliseconds to wait
1662 nanos........nanoseconds to wait
1664 *******************************************************************************/
1666 void threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1669 struct timespec wakeupTime;
1671 /* calculate the the (latest) wakeup time */
1673 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1677 threads_wait_with_timeout(thread, &wakeupTime);
1681 /* threads_calc_absolute_time **************************************************
1683 Calculate the absolute point in time a given number of ms and ns from now.
1686 millis............milliseconds from now
1687 nanos.............nanoseconds from now
1690 *tm...............receives the timespec of the absolute point in time
1692 *******************************************************************************/
1694 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1696 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1699 gettimeofday(&tv, NULL);
1700 tv.tv_sec += millis / 1000;
1702 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1703 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1704 tm->tv_nsec = nsec % 1000000000;
1713 /* threads_thread_interrupt ****************************************************
1715 Interrupt the given thread.
1717 The thread gets the "waitcond" signal and
1718 its interrupted flag is set to true.
1721 thread............the thread to interrupt
1723 *******************************************************************************/
1725 void threads_thread_interrupt(threadobject *thread)
1727 /* Signal the thread a "waitcond" and tell it that it has been
1730 mutex_lock(&thread->waitmutex);
1732 DEBUGTHREADS("interrupted", thread);
1734 /* Interrupt blocking system call using a signal. */
1736 pthread_kill(thread->tid, SIGHUP);
1738 if (thread->sleeping)
1739 pthread_cond_signal(&thread->waitcond);
1741 thread->interrupted = true;
1743 mutex_unlock(&thread->waitmutex);
1747 /* threads_sleep ***************************************************************
1749 Sleep the current thread for the specified amount of time.
1751 *******************************************************************************/
1753 void threads_sleep(int64_t millis, int32_t nanos)
1756 struct timespec wakeupTime;
1760 /* exceptions_throw_illegalargumentexception("timeout value is negative"); */
1761 exceptions_throw_illegalargumentexception();
1765 t = thread_get_current();
1767 if (thread_is_interrupted(t) && !exceptions_get_exception()) {
1768 /* Clear interrupted flag (Mauve test:
1769 gnu/testlet/java/lang/Thread/interrupt). */
1771 thread_set_interrupted(t, false);
1773 /* exceptions_throw_interruptedexception("sleep interrupted"); */
1774 exceptions_throw_interruptedexception();
1778 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1780 threads_wait_with_timeout(t, &wakeupTime);
1782 interrupted = thread_is_interrupted(t);
1785 thread_set_interrupted(t, false);
1787 /* An other exception could have been thrown
1788 (e.g. ThreadDeathException). */
1790 if (!exceptions_get_exception())
1791 exceptions_throw_interruptedexception();
1796 /* threads_yield ***************************************************************
1798 Yield to the scheduler.
1800 *******************************************************************************/
1802 void threads_yield(void)
1809 * These are local overrides for various environment variables in Emacs.
1810 * Please do not remove this and leave it at the end of the file, where
1811 * Emacs will automagically detect them.
1812 * ---------------------------------------------------------------------
1815 * indent-tabs-mode: t
1819 * vim:noexpandtab:sw=4:ts=4: