+ startup = t;
+ t = NULL; /* make sure it's not used wrongly */
+
+ thread = startup->thread;
+ function = startup->function;
+ psem = startup->psem;
+
+ /* Seems like we've encountered a situation where thread->tid was not set by
+ * pthread_create. We alleviate this problem by waiting for pthread_create
+ * to return. */
+ threads_sem_wait(startup->psem_first);
+
+ /* set the thread object */
+
+#if defined(__DARWIN__)
+ thread->mach_thread = mach_thread_self();
+#endif
+ threads_set_current_threadobject(thread);
+
+ /* insert the thread into the threadlist and the threads table */
+
+ pthread_mutex_lock(&threadlistlock);
+
+ thread->prev = mainthreadobj;
+ thread->next = tnext = mainthreadobj->next;
+ mainthreadobj->next = thread;
+ tnext->prev = thread;
+
+ threads_table_add(thread);
+
+ pthread_mutex_unlock(&threadlistlock);
+
+ /* init data structures of this thread */
+
+ lock_init_execution_env(thread);
+
+ /* tell threads_startup_thread that we registered ourselves */
+ /* CAUTION: *startup becomes invalid with this! */
+
+ startup = NULL;
+ threads_sem_post(psem);
+
+ /* set our priority */
+
+ threads_set_thread_priority(thread->tid, thread->object->priority);
+
+#if defined(ENABLE_INTRP)
+ /* set interpreter stack */
+
+ if (opt_intrp)
+ thread->_global_sp = (Cell *) (intrp_thread_stack + opt_stacksize);
+#endif
+
+#if defined(ENABLE_JVMTI)
+ /* fire thread start event */
+
+ if (jvmti)
+ jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_START);
+#endif
+
+ /* find and run the Thread.run()V method if no other function was passed */
+
+ if (function == NULL) {
+ /* this is a normal Java thread */
+
+ thread->flags |= THREAD_FLAG_JAVA;
+
+#if defined(WITH_CLASSPATH_GNU)
+ /* We need to start the run method of
+ java.lang.VMThread. Since this is a final class, we can use
+ the class object directly. */
+
+ c = class_java_lang_VMThread;
+#elif defined(WITH_CLASSPATH_CLDC1_1)
+ c = thread->object->header.vftbl->class;
+#endif
+
+ m = class_resolveclassmethod(c, utf_run, utf_void__void, c, true);
+
+ if (m == NULL)
+ throw_exception();
+
+ /* set ThreadMXBean variables */
+
+ _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
+ _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
+
+ if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
+ _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
+ _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
+ _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
+
+#if defined(WITH_CLASSPATH_GNU)
+ /* we need to start the run method of java.lang.VMThread */
+
+ vmt = (java_lang_VMThread *) thread->object->vmThread;
+ o = (java_objectheader *) vmt;
+
+#elif defined(WITH_CLASSPATH_CLDC1_1)
+ o = (java_objectheader *) thread->object;
+#endif
+
+ (void) vm_call_method(m, o);
+ }
+ else {
+ /* this is an internal thread */
+
+ thread->flags |= THREAD_FLAG_INTERNAL;
+
+ /* set ThreadMXBean variables */
+
+ _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
+ _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
+
+ if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
+ _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
+ _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
+ _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
+
+ /* call passed function, e.g. finalizer_thread */
+
+ (function)();
+ }
+
+#if defined(ENABLE_JVMTI)
+ /* fire thread end event */
+
+ if (jvmti)
+ jvmti_ThreadStartEnd(JVMTI_EVENT_THREAD_END);
+#endif
+
+ threads_detach_thread(thread);
+
+ /* set ThreadMXBean variables */
+
+ _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount--;
+
+ return NULL;