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 7669 2007-04-05 11:39:58Z 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(ENABLE_STATISTICS)
92 # include "vmcore/statistics.h"
95 #if !defined(__DARWIN__)
96 # if defined(__LINUX__)
97 # define GC_LINUX_THREADS
98 # elif defined(__MIPS__)
99 # define GC_IRIX_THREADS
101 # include <semaphore.h>
102 # if defined(ENABLE_GC_BOEHM)
103 # include "mm/boehm-gc/include/gc.h"
107 #if defined(ENABLE_JVMTI)
108 #include "native/jvmti/cacaodbg.h"
111 #if defined(__DARWIN__)
112 /* Darwin has no working semaphore implementation. This one is taken
116 This is a very simple semaphore implementation for darwin. It
117 is implemented in terms of pthreads calls so it isn't async signal
118 safe. This isn't a problem because signals aren't used to
119 suspend threads on darwin.
122 static int sem_init(sem_t *sem, int pshared, int value)
129 if (pthread_mutex_init(&sem->mutex, NULL) < 0)
132 if (pthread_cond_init(&sem->cond, NULL) < 0)
138 static int sem_post(sem_t *sem)
140 if (pthread_mutex_lock(&sem->mutex) < 0)
145 if (pthread_cond_signal(&sem->cond) < 0) {
146 pthread_mutex_unlock(&sem->mutex);
150 if (pthread_mutex_unlock(&sem->mutex) < 0)
156 static int sem_wait(sem_t *sem)
158 if (pthread_mutex_lock(&sem->mutex) < 0)
161 while (sem->value == 0) {
162 pthread_cond_wait(&sem->cond, &sem->mutex);
167 if (pthread_mutex_unlock(&sem->mutex) < 0)
173 static int sem_destroy(sem_t *sem)
175 if (pthread_cond_destroy(&sem->cond) < 0)
178 if (pthread_mutex_destroy(&sem->mutex) < 0)
183 #endif /* defined(__DARWIN__) */
186 /* internally used constants **************************************************/
188 /* CAUTION: Do not change these values. Boehm GC code depends on them. */
189 #define STOPWORLD_FROM_GC 1
190 #define STOPWORLD_FROM_CLASS_NUMBERING 2
192 #define THREADS_INITIAL_TABLE_SIZE 8
195 /* startupinfo *****************************************************************
197 Struct used to pass info from threads_start_thread to
198 threads_startup_thread.
200 ******************************************************************************/
203 threadobject *thread; /* threadobject for this thread */
204 functionptr function; /* function to run in the new thread */
205 sem_t *psem; /* signals when thread has been entered */
206 /* in the thread list */
207 sem_t *psem_first; /* signals when pthread_create has returned */
211 /* prototypes *****************************************************************/
213 static void threads_table_init(void);
214 static s4 threads_table_add(threadobject *thread);
215 static void threads_table_remove(threadobject *thread);
216 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos);
218 #if !defined(NDEBUG) && 0
219 static void threads_table_dump(FILE *file);
222 /******************************************************************************/
223 /* GLOBAL VARIABLES */
224 /******************************************************************************/
226 /* the main thread */
227 threadobject *mainthreadobj;
229 static methodinfo *method_thread_init;
231 /* the thread object of the current thread */
232 /* This is either a thread-local variable defined with __thread, or */
233 /* a thread-specific value stored with key threads_current_threadobject_key. */
234 #if defined(HAVE___THREAD)
235 __thread threadobject *threads_current_threadobject;
237 pthread_key_t threads_current_threadobject_key;
240 /* global threads table */
241 static threads_table_t threads_table;
243 /* global compiler mutex */
244 static pthread_mutex_t compiler_mutex;
246 /* global mutex for changing the thread list */
247 static pthread_mutex_t threadlistlock;
249 /* global mutex for stop-the-world */
250 static pthread_mutex_t stopworldlock;
252 /* this is one of the STOPWORLD_FROM_ constants, telling why the world is */
254 static volatile int stopworldwhere;
256 /* semaphore used for acknowleding thread suspension */
257 static sem_t suspend_ack;
258 #if defined(__MIPS__)
259 static pthread_mutex_t suspend_ack_lock = PTHREAD_MUTEX_INITIALIZER;
260 static pthread_cond_t suspend_cond = PTHREAD_COND_INITIALIZER;
263 static pthread_attr_t threadattr;
265 /* mutexes used by the fake atomic instructions */
266 #if defined(USE_FAKE_ATOMIC_INSTRUCTIONS)
267 pthread_mutex_t _atomic_add_lock = PTHREAD_MUTEX_INITIALIZER;
268 pthread_mutex_t _cas_lock = PTHREAD_MUTEX_INITIALIZER;
269 pthread_mutex_t _mb_lock = PTHREAD_MUTEX_INITIALIZER;
273 /* threads_sem_init ************************************************************
275 Initialize a semaphore. Checks against errors and interruptions.
278 sem..............the semaphore to initialize
279 shared...........true if this semaphore will be shared between processes
280 value............the initial value for the semaphore
282 *******************************************************************************/
284 void threads_sem_init(sem_t *sem, bool shared, int value)
291 r = sem_init(sem, shared, value);
294 } while (errno == EINTR);
296 vm_abort("sem_init failed: %s", strerror(errno));
300 /* threads_sem_wait ************************************************************
302 Wait for a semaphore, non-interruptible.
304 IMPORTANT: Always use this function instead of `sem_wait` directly, as
305 `sem_wait` may be interrupted by signals!
308 sem..............the semaphore to wait on
310 *******************************************************************************/
312 void threads_sem_wait(sem_t *sem)
322 } while (errno == EINTR);
324 vm_abort("sem_wait failed: %s", strerror(errno));
328 /* threads_sem_post ************************************************************
330 Increase the count of a semaphore. Checks for errors.
333 sem..............the semaphore to increase the count of
335 *******************************************************************************/
337 void threads_sem_post(sem_t *sem)
343 /* unlike sem_wait, sem_post is not interruptible */
349 vm_abort("sem_post failed: %s", strerror(errno));
353 /* compiler_lock ***************************************************************
355 Enter the compiler lock.
357 ******************************************************************************/
359 void compiler_lock(void)
361 pthread_mutex_lock(&compiler_mutex);
365 /* compiler_unlock *************************************************************
367 Release the compiler lock.
369 ******************************************************************************/
371 void compiler_unlock(void)
373 pthread_mutex_unlock(&compiler_mutex);
377 /* lock_stopworld **************************************************************
379 Enter the stopworld lock, specifying why the world shall be stopped.
382 where........ STOPWORLD_FROM_GC (1) from within GC
383 STOPWORLD_FROM_CLASS_NUMBERING (2) class numbering
385 ******************************************************************************/
387 void lock_stopworld(int where)
389 pthread_mutex_lock(&stopworldlock);
390 stopworldwhere = where;
394 /* unlock_stopworld ************************************************************
396 Release the stopworld lock.
398 ******************************************************************************/
400 void unlock_stopworld(void)
403 pthread_mutex_unlock(&stopworldlock);
406 #if !defined(__DARWIN__)
407 /* Caller must hold threadlistlock */
408 static int threads_cast_sendsignals(int sig, int count)
411 threadobject *tobj = mainthreadobj;
412 threadobject *self = THREADOBJECT;
418 } while (tobj != mainthreadobj);
421 assert(tobj == mainthreadobj);
425 pthread_kill(tobj->tid, sig);
427 } while (tobj != mainthreadobj);
434 static void threads_cast_darwinstop(void)
436 threadobject *tobj = mainthreadobj;
437 threadobject *self = THREADOBJECT;
442 thread_state_flavor_t flavor = MACHINE_THREAD_STATE;
443 mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
444 #if defined(__I386__)
445 i386_thread_state_t thread_state;
447 ppc_thread_state_t thread_state;
449 mach_port_t thread = tobj->mach_thread;
452 r = thread_suspend(thread);
454 if (r != KERN_SUCCESS)
455 vm_abort("thread_suspend failed");
457 r = thread_get_state(thread, flavor, (natural_t *) &thread_state,
458 &thread_state_count);
460 if (r != KERN_SUCCESS)
461 vm_abort("thread_get_state failed");
463 thread_restartcriticalsection((ucontext_t *) &thread_state);
465 r = thread_set_state(thread, flavor, (natural_t *) &thread_state,
468 if (r != KERN_SUCCESS)
469 vm_abort("thread_set_state failed");
473 } while (tobj != mainthreadobj);
476 static void threads_cast_darwinresume(void)
478 threadobject *tobj = mainthreadobj;
479 threadobject *self = THREADOBJECT;
484 mach_port_t thread = tobj->mach_thread;
487 r = thread_resume(thread);
489 if (r != KERN_SUCCESS)
490 vm_abort("thread_resume failed");
494 } while (tobj != mainthreadobj);
499 #if defined(__MIPS__)
500 static void threads_cast_irixresume(void)
502 pthread_mutex_lock(&suspend_ack_lock);
503 pthread_cond_broadcast(&suspend_cond);
504 pthread_mutex_unlock(&suspend_ack_lock);
508 #if !defined(DISABLE_GC)
510 void threads_cast_stopworld(void)
512 #if !defined(__DARWIN__) && !defined(__CYGWIN__)
516 lock_stopworld(STOPWORLD_FROM_CLASS_NUMBERING);
517 pthread_mutex_lock(&threadlistlock);
519 #if defined(__DARWIN__)
520 threads_cast_darwinstop();
521 #elif defined(__CYGWIN__)
525 count = threads_cast_sendsignals(GC_signum1(), 0);
526 for (i = 0; i < count; i++)
527 threads_sem_wait(&suspend_ack);
530 pthread_mutex_unlock(&threadlistlock);
533 void threads_cast_startworld(void)
535 pthread_mutex_lock(&threadlistlock);
536 #if defined(__DARWIN__)
537 threads_cast_darwinresume();
538 #elif defined(__MIPS__)
539 threads_cast_irixresume();
540 #elif defined(__CYGWIN__)
544 threads_cast_sendsignals(GC_signum2(), -1);
546 pthread_mutex_unlock(&threadlistlock);
551 #if !defined(__DARWIN__)
552 static void threads_sigsuspend_handler(ucontext_t *ctx)
557 /* XXX TWISTI: this is just a quick hack */
558 #if defined(ENABLE_JIT)
559 thread_restartcriticalsection(ctx);
562 /* Do as Boehm does. On IRIX a condition variable is used for wake-up
563 (not POSIX async-safe). */
564 #if defined(__IRIX__)
565 pthread_mutex_lock(&suspend_ack_lock);
566 threads_sem_post(&suspend_ack);
567 pthread_cond_wait(&suspend_cond, &suspend_ack_lock);
568 pthread_mutex_unlock(&suspend_ack_lock);
569 #elif defined(__CYGWIN__)
573 threads_sem_post(&suspend_ack);
577 sigdelset(&sigs, sig);
582 /* This function is called from Boehm GC code. */
584 int cacao_suspendhandler(ucontext_t *ctx)
586 if (stopworldwhere != STOPWORLD_FROM_CLASS_NUMBERING)
589 threads_sigsuspend_handler(ctx);
594 #endif /* DISABLE_GC */
596 /* threads_set_current_threadobject ********************************************
598 Set the current thread object.
601 thread.......the thread object to set
603 *******************************************************************************/
605 static void threads_set_current_threadobject(threadobject *thread)
607 #if !defined(HAVE___THREAD)
608 pthread_setspecific(threads_current_threadobject_key, thread);
610 threads_current_threadobject = thread;
615 /* threads_init_threadobject **************************************************
617 Initialize implementation fields of a threadobject.
620 thread............the threadobject
622 ******************************************************************************/
624 static void threads_init_threadobject(threadobject *thread)
626 thread->tid = pthread_self();
630 /* TODO destroy all those things */
631 pthread_mutex_init(&(thread->joinmutex), NULL);
632 pthread_cond_init(&(thread->joincond), NULL);
634 pthread_mutex_init(&(thread->waitmutex), NULL);
635 pthread_cond_init(&(thread->waitcond), NULL);
637 thread->interrupted = false;
638 thread->signaled = false;
639 thread->sleeping = false;
643 /* threads_get_current_threadobject ********************************************
645 Return the threadobject of the current thread.
648 the current threadobject * (an instance of java.lang.Thread)
650 *******************************************************************************/
652 threadobject *threads_get_current_threadobject(void)
658 /* threads_preinit *************************************************************
660 Do some early initialization of stuff required.
662 ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
663 is called AFTER this function!
665 *******************************************************************************/
667 void threads_preinit(void)
669 pthread_mutexattr_t mutexattr;
670 pthread_mutexattr_init(&mutexattr);
671 pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
672 pthread_mutex_init(&compiler_mutex, &mutexattr);
673 pthread_mutexattr_destroy(&mutexattr);
675 pthread_mutex_init(&threadlistlock, NULL);
676 pthread_mutex_init(&stopworldlock, NULL);
678 mainthreadobj = NEW(threadobject);
680 #if defined(ENABLE_STATISTICS)
682 size_threadobject += sizeof(threadobject);
685 mainthreadobj->object = NULL;
686 mainthreadobj->tid = pthread_self();
687 mainthreadobj->index = 1;
688 mainthreadobj->thinlock = lock_pre_compute_thinlock(mainthreadobj->index);
690 #if !defined(HAVE___THREAD)
691 pthread_key_create(&threads_current_threadobject_key, NULL);
693 threads_set_current_threadobject(mainthreadobj);
695 threads_sem_init(&suspend_ack, 0, 0);
697 /* initialize the threads table */
699 threads_table_init();
701 /* initialize subsystems */
709 /* threads_init ****************************************************************
711 Initializes the threads required by the JVM: main, finalizer.
713 *******************************************************************************/
715 bool threads_init(void)
717 java_lang_String *threadname;
718 threadobject *tempthread;
719 java_objectheader *o;
721 #if defined(ENABLE_JAVASE)
722 java_lang_ThreadGroup *threadgroup;
727 #if defined(WITH_CLASSPATH_GNU)
728 java_lang_VMThread *vmt;
731 tempthread = mainthreadobj;
733 /* XXX We have to find a new way to free lock records */
734 /* with the new locking algorithm. */
735 /* lock_record_free_pools(mainthreadobj->ee.lockrecordpools); */
738 /* This is kinda tricky, we grow the java.lang.Thread object so we
739 can keep the execution environment there. No Thread object must
740 have been created at an earlier time. */
742 class_java_lang_Thread->instancesize = sizeof(threadobject);
745 /* get methods we need in this file */
747 #if defined(WITH_CLASSPATH_GNU)
749 class_resolveclassmethod(class_java_lang_Thread,
751 utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
752 class_java_lang_Thread,
756 class_resolveclassmethod(class_java_lang_Thread,
758 utf_new_char("(Ljava/lang/String;)V"),
759 class_java_lang_Thread,
763 if (method_thread_init == NULL)
766 /* create a vm internal thread object for the main thread */
767 /* XXX Michi: we do not need to do this here, we could use the one
768 created by threads_preinit() */
770 #if defined(ENABLE_GC_CACAO)
771 mainthreadobj = NEW(threadobject);
773 # if defined(ENABLE_STATISTICS)
775 size_threadobject += sizeof(threadobject);
778 mainthreadobj = GCNEW(threadobject);
781 if (mainthreadobj == NULL)
784 /* create a java.lang.Thread for the main thread */
786 mainthreadobj->object = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
788 if (mainthreadobj->object == NULL)
791 FREE(tempthread, threadobject);
793 threads_init_threadobject(mainthreadobj);
794 threads_set_current_threadobject(mainthreadobj);
795 lock_init_execution_env(mainthreadobj);
797 /* thread is running */
799 mainthreadobj->state = THREAD_STATE_RUNNABLE;
801 mainthreadobj->next = mainthreadobj;
802 mainthreadobj->prev = mainthreadobj;
804 threads_table_add(mainthreadobj);
806 /* mark main thread as Java thread */
808 mainthreadobj->flags = THREAD_FLAG_JAVA;
810 #if defined(ENABLE_INTRP)
811 /* create interpreter stack */
814 MSET(intrp_main_stack, 0, u1, opt_stacksize);
815 mainthreadobj->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
819 threadname = javastring_new(utf_new_char("main"));
821 #if defined(ENABLE_JAVASE)
822 /* allocate and init ThreadGroup */
824 threadgroup = (java_lang_ThreadGroup *)
825 native_new_and_init(class_java_lang_ThreadGroup);
827 if (threadgroup == NULL)
831 #if defined(WITH_CLASSPATH_GNU)
832 /* create a java.lang.VMThread for the main thread */
834 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
841 vmt->thread = mainthreadobj->object;
842 vmt->vmdata = (java_lang_Object *) mainthreadobj;
844 /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
845 o = (java_objectheader *) mainthreadobj->object;
847 (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
849 #elif defined(WITH_CLASSPATH_CLDC1_1)
852 mainthreadobj->object->vm_thread = (java_lang_Object *) mainthreadobj;
854 /* call public Thread(String name) */
856 o = (java_objectheader *) mainthreadobj->object;
858 (void) vm_call_method(method_thread_init, o, threadname);
864 #if defined(ENABLE_JAVASE)
865 mainthreadobj->object->group = threadgroup;
867 /* add main thread to java.lang.ThreadGroup */
869 m = class_resolveclassmethod(class_java_lang_ThreadGroup,
871 utf_java_lang_Thread__V,
872 class_java_lang_ThreadGroup,
875 o = (java_objectheader *) threadgroup;
876 t = mainthreadobj->object;
878 (void) vm_call_method(m, o, t);
885 threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
887 /* initialize the thread attribute object */
889 if (pthread_attr_init(&threadattr)) {
890 log_println("pthread_attr_init failed: %s", strerror(errno));
894 pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
896 /* everything's ok */
902 /* threads_table_init *********************************************************
904 Initialize the global threads table.
906 ******************************************************************************/
908 static void threads_table_init(void)
913 size = THREADS_INITIAL_TABLE_SIZE;
915 threads_table.size = size;
916 threads_table.table = MNEW(threads_table_entry_t, size);
918 /* link the entries in a freelist */
920 for (i=0; i<size; ++i) {
921 threads_table.table[i].nextfree = i+1;
924 /* terminate the freelist */
926 threads_table.table[size-1].nextfree = 0; /* index 0 is never free */
930 /* threads_table_add **********************************************************
932 Add a thread to the global threads table. The index is entered in the
933 threadobject. The thinlock value for the thread is pre-computed.
936 thread............the thread to add
939 The table index for the newly added thread. This value has also been
940 entered in the threadobject.
943 The caller must hold the threadlistlock!
945 ******************************************************************************/
947 static s4 threads_table_add(threadobject *thread)
954 /* table[0] serves as the head of the freelist */
956 index = threads_table.table[0].nextfree;
958 /* if we got a free index, use it */
962 threads_table.table[0].nextfree = threads_table.table[index].nextfree;
963 threads_table.table[index].thread = thread;
964 thread->index = index;
965 thread->thinlock = lock_pre_compute_thinlock(index);
969 /* we must grow the table */
971 oldsize = threads_table.size;
972 newsize = oldsize * 2;
974 threads_table.table = MREALLOC(threads_table.table, threads_table_entry_t,
976 threads_table.size = newsize;
978 /* link the new entries to a free list */
980 for (i=oldsize; i<newsize; ++i) {
981 threads_table.table[i].nextfree = i+1;
984 /* terminate the freelist */
986 threads_table.table[newsize-1].nextfree = 0; /* index 0 is never free */
988 /* use the first of the new entries */
995 /* threads_table_remove *******************************************************
997 Remove a thread from the global threads table.
1000 thread............the thread to remove
1003 The caller must hold the threadlistlock!
1005 ******************************************************************************/
1007 static void threads_table_remove(threadobject *thread)
1011 index = thread->index;
1013 /* put the index into the freelist */
1015 threads_table.table[index] = threads_table.table[0];
1016 threads_table.table[0].nextfree = index;
1018 /* delete the index in the threadobject to discover bugs */
1019 #if !defined(NDEBUG)
1025 /* threads_startup_thread ******************************************************
1027 Thread startup function called by pthread_create.
1029 Thread which have a startup.function != NULL are marked as internal
1030 threads. All other threads are threated as normal Java threads.
1032 NOTE: This function is not called directly by pthread_create. The Boehm GC
1033 inserts its own GC_start_routine in between, which then calls
1037 t............the argument passed to pthread_create, ie. a pointer to
1038 a startupinfo struct. CAUTION: When the `psem` semaphore
1039 is posted, the startupinfo struct becomes invalid! (It
1040 is allocated on the stack of threads_start_thread.)
1042 ******************************************************************************/
1044 static void *threads_startup_thread(void *t)
1046 startupinfo *startup;
1047 threadobject *thread;
1048 #if defined(WITH_CLASSPATH_GNU)
1049 java_lang_VMThread *vmt;
1052 threadobject *tnext;
1055 java_objectheader *o;
1056 functionptr function;
1058 #if defined(ENABLE_INTRP)
1059 u1 *intrp_thread_stack;
1061 /* create interpreter stack */
1064 intrp_thread_stack = GCMNEW(u1, opt_stacksize);
1065 MSET(intrp_thread_stack, 0, u1, opt_stacksize);
1068 intrp_thread_stack = NULL;
1071 /* get passed startupinfo structure and the values in there */
1074 t = NULL; /* make sure it's not used wrongly */
1076 thread = startup->thread;
1077 function = startup->function;
1078 psem = startup->psem;
1080 /* Seems like we've encountered a situation where thread->tid was not set by
1081 * pthread_create. We alleviate this problem by waiting for pthread_create
1083 threads_sem_wait(startup->psem_first);
1085 /* set the thread object */
1087 #if defined(__DARWIN__)
1088 thread->mach_thread = mach_thread_self();
1090 threads_set_current_threadobject(thread);
1092 /* thread is running */
1094 thread->state = THREAD_STATE_RUNNABLE;
1096 /* insert the thread into the threadlist and the threads table */
1098 pthread_mutex_lock(&threadlistlock);
1100 thread->prev = mainthreadobj;
1101 thread->next = tnext = mainthreadobj->next;
1102 mainthreadobj->next = thread;
1103 tnext->prev = thread;
1105 threads_table_add(thread);
1107 pthread_mutex_unlock(&threadlistlock);
1109 /* init data structures of this thread */
1111 lock_init_execution_env(thread);
1113 /* tell threads_startup_thread that we registered ourselves */
1114 /* CAUTION: *startup becomes invalid with this! */
1117 threads_sem_post(psem);
1119 /* set our priority */
1121 threads_set_thread_priority(thread->tid, thread->object->priority);
1123 #if defined(ENABLE_INTRP)
1124 /* set interpreter stack */
1127 thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
1130 #if defined(ENABLE_JVMTI)
1131 /* fire thread start event */
1134 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
1137 /* find and run the Thread.run()V method if no other function was passed */
1139 if (function == NULL) {
1140 /* this is a normal Java thread */
1142 thread->flags |= THREAD_FLAG_JAVA;
1144 #if defined(WITH_CLASSPATH_GNU)
1145 /* We need to start the run method of
1146 java.lang.VMThread. Since this is a final class, we can use
1147 the class object directly. */
1149 c = class_java_lang_VMThread;
1150 #elif defined(WITH_CLASSPATH_CLDC1_1)
1151 c = thread->object->header.vftbl->class;
1154 m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
1157 vm_abort("threads_startup_thread: run() method not found in class");
1159 /* set ThreadMXBean variables */
1161 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1162 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1164 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1165 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1166 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1167 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1169 #if defined(WITH_CLASSPATH_GNU)
1170 /* we need to start the run method of java.lang.VMThread */
1172 vmt = (java_lang_VMThread *) thread->object->vmThread;
1173 o = (java_objectheader *) vmt;
1175 #elif defined(WITH_CLASSPATH_CLDC1_1)
1176 o = (java_objectheader *) thread->object;
1179 /* run the thread */
1181 (void) vm_call_method(m, o);
1184 /* this is an internal thread */
1186 thread->flags |= THREAD_FLAG_INTERNAL;
1188 /* set ThreadMXBean variables */
1190 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1191 _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1193 if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1194 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1195 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1196 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1198 /* call passed function, e.g. finalizer_thread */
1203 #if defined(ENABLE_JVMTI)
1204 /* fire thread end event */
1207 jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
1210 threads_detach_thread(thread);
1212 /* set ThreadMXBean variables */
1214 _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
1220 /* threads_start_javathread ***************************************************
1222 Start a thread in the JVM. Only the java thread object exists so far.
1225 object.....the java thread object java.lang.Thread
1227 ******************************************************************************/
1229 void threads_start_javathread(java_lang_Thread *object)
1231 threadobject *thread;
1233 /* create the vm internal threadobject */
1235 thread = NEW(threadobject);
1237 #if defined(ENABLE_STATISTICS)
1239 size_threadobject += sizeof(threadobject);
1242 /* link the two objects together */
1244 thread->object = object;
1246 #if defined(WITH_CLASSPATH_GNU)
1247 assert(object->vmThread);
1248 assert(object->vmThread->vmdata == NULL);
1249 object->vmThread->vmdata = (java_lang_Object *) thread;
1250 #elif defined(WITH_CLASSPATH_CLDC1_1)
1251 object->vm_thread = (java_lang_Object *) thread;
1254 /* actually start the thread */
1255 /* don't pass a function pointer (NULL) since we want Thread.run()V here */
1257 threads_start_thread(thread, NULL);
1261 /* threads_start_thread ********************************************************
1263 Start a thread in the JVM. Both (vm internal and java) thread objects exist.
1266 thread.......the thread object
1267 function.....function to run in the new thread. NULL means that the
1268 "run" method of the object `t` should be called
1270 ******************************************************************************/
1272 void threads_start_thread(threadobject *thread, functionptr function)
1276 pthread_attr_t attr;
1277 startupinfo startup;
1279 /* fill startupinfo structure passed by pthread_create to
1280 * threads_startup_thread */
1282 startup.thread = thread;
1283 startup.function = function; /* maybe we don't call Thread.run()V */
1284 startup.psem = &sem;
1285 startup.psem_first = &sem_first;
1287 threads_sem_init(&sem, 0, 0);
1288 threads_sem_init(&sem_first, 0, 0);
1290 /* initialize thread attribute object */
1292 if (pthread_attr_init(&attr))
1293 vm_abort("pthread_attr_init failed: %s", strerror(errno));
1295 /* initialize thread stacksize */
1297 if (pthread_attr_setstacksize(&attr, opt_stacksize))
1298 vm_abort("pthread_attr_setstacksize failed: %s", strerror(errno));
1300 /* create the thread */
1302 if (pthread_create(&(thread->tid), &attr, threads_startup_thread, &startup))
1303 vm_abort("pthread_create failed: %s", strerror(errno));
1305 /* signal that pthread_create has returned, so thread->tid is valid */
1307 threads_sem_post(&sem_first);
1309 /* wait here until the thread has entered itself into the thread list */
1311 threads_sem_wait(&sem);
1316 sem_destroy(&sem_first);
1320 /* threads_set_thread_priority *************************************************
1322 Set the priority of the given thread.
1325 tid..........thread id
1326 priority.....priority to set
1328 ******************************************************************************/
1330 void threads_set_thread_priority(pthread_t tid, int priority)
1332 struct sched_param schedp;
1335 pthread_getschedparam(tid, &policy, &schedp);
1336 schedp.sched_priority = priority;
1337 pthread_setschedparam(tid, policy, &schedp);
1341 /* threads_attach_current_thread ***********************************************
1343 Attaches the current thread to the VM. Used in JNI.
1345 *******************************************************************************/
1347 bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
1349 threadobject *thread;
1351 java_lang_String *s;
1352 java_objectheader *o;
1353 java_lang_Thread *t;
1355 #if defined(ENABLE_JAVASE)
1356 java_lang_ThreadGroup *group;
1360 #if defined(WITH_CLASSPATH_GNU)
1361 java_lang_VMThread *vmt;
1364 /* create a vm internal thread object */
1366 thread = NEW(threadobject);
1368 #if defined(ENABLE_STATISTICS)
1370 size_threadobject += sizeof(threadobject);
1376 /* create a java.lang.Thread object */
1378 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
1385 threads_init_threadobject(thread);
1386 threads_set_current_threadobject(thread);
1387 lock_init_execution_env(thread);
1389 /* thread is running */
1391 thread->state = THREAD_STATE_RUNNABLE;
1393 /* insert the thread into the threadlist and the threads table */
1395 pthread_mutex_lock(&threadlistlock);
1397 thread->prev = mainthreadobj;
1398 thread->next = mainthreadobj->next;
1399 mainthreadobj->next = thread;
1400 thread->next->prev = thread;
1402 threads_table_add(thread);
1404 pthread_mutex_unlock(&threadlistlock);
1406 /* mark thread as Java thread */
1408 thread->flags = THREAD_FLAG_JAVA;
1411 thread->flags |= THREAD_FLAG_DAEMON;
1413 #if defined(ENABLE_INTRP)
1414 /* create interpreter stack */
1417 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1418 thread->_global_sp = (Cell *) (intrp_main_stack + opt_stacksize);
1422 #if defined(WITH_CLASSPATH_GNU)
1423 /* create a java.lang.VMThread object */
1425 vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
1430 /* set the thread */
1433 vmt->vmdata = (java_lang_Object *) thread;
1434 #elif defined(WITH_CLASSPATH_CLDC1_1)
1435 t->vm_thread = (java_lang_Object *) thread;
1438 if (vm_aargs != NULL) {
1439 u = utf_new_char(vm_aargs->name);
1440 #if defined(ENABLE_JAVASE)
1441 group = (java_lang_ThreadGroup *) vm_aargs->group;
1446 #if defined(ENABLE_JAVASE)
1447 group = mainthreadobj->object->group;
1451 s = javastring_new(u);
1453 o = (java_objectheader *) thread->object;
1455 #if defined(WITH_CLASSPATH_GNU)
1456 (void) vm_call_method(method_thread_init, o, vmt, s, NORM_PRIORITY,
1458 #elif defined(WITH_CLASSPATH_CLDC1_1)
1459 (void) vm_call_method(method_thread_init, o, s);
1465 #if defined(ENABLE_JAVASE)
1466 /* store the thread group in the object */
1468 thread->object->group = group;
1470 /* add thread to given thread-group */
1472 m = class_resolveclassmethod(group->header.vftbl->class,
1474 utf_java_lang_Thread__V,
1475 class_java_lang_ThreadGroup,
1478 o = (java_objectheader *) group;
1480 (void) vm_call_method(m, o, t);
1490 /* threads_detach_thread *******************************************************
1492 Detaches the passed thread from the VM. Used in JNI.
1494 *******************************************************************************/
1496 bool threads_detach_thread(threadobject *thread)
1498 #if defined(ENABLE_JAVASE)
1499 java_lang_ThreadGroup *group;
1501 java_objectheader *o;
1502 java_lang_Thread *t;
1505 /* Allow lock record pools to be used by other threads. They
1506 cannot be deleted so we'd better not waste them. */
1508 /* XXX We have to find a new way to free lock records */
1509 /* with the new locking algorithm. */
1510 /* lock_record_free_pools(thread->ee.lockrecordpools); */
1512 /* XXX implement uncaught exception stuff (like JamVM does) */
1514 #if defined(ENABLE_JAVASE)
1515 /* remove thread from the thread group */
1517 group = thread->object->group;
1519 /* XXX TWISTI: should all threads be in a ThreadGroup? */
1521 if (group != NULL) {
1522 m = class_resolveclassmethod(group->header.vftbl->class,
1524 utf_java_lang_Thread__V,
1525 class_java_lang_ThreadGroup,
1531 o = (java_objectheader *) group;
1534 (void) vm_call_method(m, o, t);
1541 /* thread is terminated */
1543 thread->state = THREAD_STATE_TERMINATED;
1545 /* remove thread from thread list and threads table, do this
1548 pthread_mutex_lock(&threadlistlock);
1550 thread->next->prev = thread->prev;
1551 thread->prev->next = thread->next;
1553 threads_table_remove(thread);
1555 pthread_mutex_unlock(&threadlistlock);
1557 /* reset thread id (lock on joinmutex? TWISTI) */
1559 pthread_mutex_lock(&(thread->joinmutex));
1561 pthread_mutex_unlock(&(thread->joinmutex));
1563 /* tell everyone that a thread has finished */
1565 pthread_cond_broadcast(&(thread->joincond));
1567 /* free the vm internal thread object */
1569 FREE(thread, threadobject);
1571 #if defined(ENABLE_STATISTICS)
1573 size_threadobject -= sizeof(threadobject);
1580 /* threads_find_non_daemon_thread **********************************************
1582 Helper function used by threads_join_all_threads for finding
1583 non-daemon threads that are still running.
1585 *******************************************************************************/
1587 /* At the end of the program, we wait for all running non-daemon
1590 static threadobject *threads_find_non_daemon_thread(threadobject *thread)
1592 while (thread != mainthreadobj) {
1593 if (!(thread->flags & THREAD_FLAG_DAEMON))
1596 thread = thread->prev;
1603 /* threads_join_all_threads ****************************************************
1605 Join all non-daemon threads.
1607 *******************************************************************************/
1609 void threads_join_all_threads(void)
1611 threadobject *thread;
1613 pthread_mutex_lock(&threadlistlock);
1615 while ((thread = threads_find_non_daemon_thread(mainthreadobj->prev)) != NULL) {
1616 pthread_mutex_lock(&(thread->joinmutex));
1618 pthread_mutex_unlock(&threadlistlock);
1621 pthread_cond_wait(&(thread->joincond), &(thread->joinmutex));
1623 pthread_mutex_unlock(&(thread->joinmutex));
1625 pthread_mutex_lock(&threadlistlock);
1628 pthread_mutex_unlock(&threadlistlock);
1632 /* threads_timespec_earlier ****************************************************
1634 Return true if timespec tv1 is earlier than timespec tv2.
1637 tv1..........first timespec
1638 tv2..........second timespec
1641 true, if the first timespec is earlier
1643 *******************************************************************************/
1645 static inline bool threads_timespec_earlier(const struct timespec *tv1,
1646 const struct timespec *tv2)
1648 return (tv1->tv_sec < tv2->tv_sec)
1650 (tv1->tv_sec == tv2->tv_sec && tv1->tv_nsec < tv2->tv_nsec);
1654 /* threads_current_time_is_earlier_than ****************************************
1656 Check if the current time is earlier than the given timespec.
1659 tv...........the timespec to compare against
1662 true, if the current time is earlier
1664 *******************************************************************************/
1666 static bool threads_current_time_is_earlier_than(const struct timespec *tv)
1668 struct timeval tvnow;
1669 struct timespec tsnow;
1671 /* get current time */
1673 if (gettimeofday(&tvnow, NULL) != 0)
1674 vm_abort("gettimeofday failed: %s\n", strerror(errno));
1676 /* convert it to a timespec */
1678 tsnow.tv_sec = tvnow.tv_sec;
1679 tsnow.tv_nsec = tvnow.tv_usec * 1000;
1681 /* compare current time with the given timespec */
1683 return threads_timespec_earlier(&tsnow, tv);
1687 /* threads_wait_with_timeout ***************************************************
1689 Wait until the given point in time on a monitor until either
1690 we are notified, we are interrupted, or the time is up.
1693 t............the current thread
1694 wakeupTime...absolute (latest) wakeup time
1695 If both tv_sec and tv_nsec are zero, this function
1696 waits for an unlimited amount of time.
1699 true.........if the wait has been interrupted,
1700 false........if the wait was ended by notification or timeout
1702 *******************************************************************************/
1704 static bool threads_wait_with_timeout(threadobject *thread,
1705 struct timespec *wakeupTime)
1707 bool wasinterrupted;
1709 /* acquire the waitmutex */
1711 pthread_mutex_lock(&thread->waitmutex);
1713 /* mark us as sleeping */
1715 thread->sleeping = true;
1717 /* wait on waitcond */
1719 if (wakeupTime->tv_sec || wakeupTime->tv_nsec) {
1721 while (!thread->interrupted && !thread->signaled
1722 && threads_current_time_is_earlier_than(wakeupTime))
1724 thread->state = THREAD_STATE_TIMED_WAITING;
1726 pthread_cond_timedwait(&thread->waitcond, &thread->waitmutex,
1729 thread->state = THREAD_STATE_RUNNABLE;
1734 while (!thread->interrupted && !thread->signaled) {
1735 thread->state = THREAD_STATE_WAITING;
1737 pthread_cond_wait(&thread->waitcond, &thread->waitmutex);
1739 thread->state = THREAD_STATE_RUNNABLE;
1743 /* check if we were interrupted */
1745 wasinterrupted = thread->interrupted;
1747 /* reset all flags */
1749 thread->interrupted = false;
1750 thread->signaled = false;
1751 thread->sleeping = false;
1753 /* release the waitmutex */
1755 pthread_mutex_unlock(&thread->waitmutex);
1757 return wasinterrupted;
1761 /* threads_wait_with_timeout_relative ******************************************
1763 Wait for the given maximum amount of time on a monitor until either
1764 we are notified, we are interrupted, or the time is up.
1767 t............the current thread
1768 millis.......milliseconds to wait
1769 nanos........nanoseconds to wait
1772 true.........if the wait has been interrupted,
1773 false........if the wait was ended by notification or timeout
1775 *******************************************************************************/
1777 bool threads_wait_with_timeout_relative(threadobject *thread, s8 millis,
1780 struct timespec wakeupTime;
1782 /* calculate the the (latest) wakeup time */
1784 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1788 return threads_wait_with_timeout(thread, &wakeupTime);
1792 /* threads_calc_absolute_time **************************************************
1794 Calculate the absolute point in time a given number of ms and ns from now.
1797 millis............milliseconds from now
1798 nanos.............nanoseconds from now
1801 *tm...............receives the timespec of the absolute point in time
1803 *******************************************************************************/
1805 static void threads_calc_absolute_time(struct timespec *tm, s8 millis, s4 nanos)
1807 if ((millis != 0x7fffffffffffffffLLU) && (millis || nanos)) {
1810 gettimeofday(&tv, NULL);
1811 tv.tv_sec += millis / 1000;
1813 nsec = tv.tv_usec * 1000 + (s4) millis * 1000000 + nanos;
1814 tm->tv_sec = tv.tv_sec + nsec / 1000000000;
1815 tm->tv_nsec = nsec % 1000000000;
1824 /* threads_thread_interrupt ****************************************************
1826 Interrupt the given thread.
1828 The thread gets the "waitcond" signal and
1829 its interrupted flag is set to true.
1832 thread............the thread to interrupt
1834 *******************************************************************************/
1836 void threads_thread_interrupt(threadobject *thread)
1838 /* Signal the thread a "waitcond" and tell it that it has been
1841 pthread_mutex_lock(&thread->waitmutex);
1843 /* Interrupt blocking system call using a signal. */
1845 pthread_kill(thread->tid, SIGHUP);
1847 if (thread->sleeping)
1848 pthread_cond_signal(&thread->waitcond);
1850 thread->interrupted = true;
1852 pthread_mutex_unlock(&thread->waitmutex);
1856 /* threads_check_if_interrupted_and_reset **************************************
1858 Check if the current thread has been interrupted and reset the
1862 true, if the current thread had been interrupted
1864 *******************************************************************************/
1866 bool threads_check_if_interrupted_and_reset(void)
1868 threadobject *thread;
1871 thread = THREADOBJECT;
1873 /* get interrupted flag */
1875 intr = thread->interrupted;
1877 /* reset interrupted flag */
1879 thread->interrupted = false;
1885 /* threads_thread_has_been_interrupted *****************************************
1887 Check if the given thread has been interrupted
1890 t............the thread to check
1893 true, if the given thread had been interrupted
1895 *******************************************************************************/
1897 bool threads_thread_has_been_interrupted(threadobject *thread)
1899 return thread->interrupted;
1903 /* threads_sleep ***************************************************************
1905 Sleep the current thread for the specified amount of time.
1907 *******************************************************************************/
1909 void threads_sleep(s8 millis, s4 nanos)
1911 threadobject *thread;
1912 struct timespec wakeupTime;
1913 bool wasinterrupted;
1915 thread = THREADOBJECT;
1917 threads_calc_absolute_time(&wakeupTime, millis, nanos);
1919 wasinterrupted = threads_wait_with_timeout(thread, &wakeupTime);
1922 exceptions_throw_interruptedexception();
1926 /* threads_yield ***************************************************************
1928 Yield to the scheduler.
1930 *******************************************************************************/
1932 void threads_yield(void)
1938 /* threads_table_dump *********************************************************
1940 Dump the threads table for debugging purposes.
1943 file..............stream to write to
1945 ******************************************************************************/
1947 #if !defined(NDEBUG) && 0
1948 static void threads_table_dump(FILE *file)
1954 pthread_mutex_lock(&threadlistlock);
1956 size = threads_table.size;
1958 fprintf(file, "======== THREADS TABLE (size %d) ========\n", size);
1960 for (i=0; i<size; ++i) {
1961 index = threads_table.table[i].nextfree;
1963 fprintf(file, "%4d: ", i);
1966 fprintf(file, "free, nextfree = %d\n", (int) index);
1969 fprintf(file, "thread %p\n", (void*) threads_table.table[i].thread);
1973 fprintf(file, "======== END OF THREADS TABLE ========\n");
1975 pthread_mutex_unlock(&threadlistlock);
1980 * These are local overrides for various environment variables in Emacs.
1981 * Please do not remove this and leave it at the end of the file, where
1982 * Emacs will automagically detect them.
1983 * ---------------------------------------------------------------------
1986 * indent-tabs-mode: t
1990 * vim:noexpandtab:sw=4:ts=4: