+ pthread_attr_t attr;
+
+ /* get methods we need in this file */
+
+#if defined(WITH_CLASSPATH_GNU)
+ method_thread_init =
+ class_resolveclassmethod(class_java_lang_Thread,
+ utf_init,
+ utf_new_char("(Ljava/lang/VMThread;Ljava/lang/String;IZ)V"),
+ class_java_lang_Thread,
+ true);
+#else
+ method_thread_init =
+ class_resolveclassmethod(class_java_lang_Thread,
+ utf_init,
+ utf_new_char("(Ljava/lang/String;)V"),
+ class_java_lang_Thread,
+ true);
+#endif
+
+ if (method_thread_init == NULL)
+ return false;
+
+ /* Get the main-thread (NOTE: The main threads is always the first
+ thread in the list). */
+
+ mainthread = threads_list_first();
+
+#if defined(ENABLE_GC_CACAO)
+ /* register reference to java.lang.Thread with the GC */
+
+ gc_reference_register((java_objectheader **) &(mainthread->object));
+#endif
+
+ /* create a java.lang.Thread for the main thread */
+
+ t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
+
+ if (t == NULL)
+ return false;
+
+ /* set the object in the internal data structure */
+
+ mainthread->object = t;
+
+#if defined(ENABLE_INTRP)
+ /* create interpreter stack */
+
+ if (opt_intrp) {
+ MSET(intrp_main_stack, 0, u1, opt_stacksize);
+ mainthread->_global_sp = (Cell*) (intrp_main_stack + opt_stacksize);
+ }
+#endif
+
+ threadname = javastring_new(utf_new_char("main"));
+
+#if defined(ENABLE_JAVASE)
+ /* allocate and init ThreadGroup */
+
+ threadgroup = (java_lang_ThreadGroup *)
+ native_new_and_init(class_java_lang_ThreadGroup);
+
+ if (threadgroup == NULL)
+ return false;
+#endif
+
+#if defined(WITH_CLASSPATH_GNU)
+ /* create a java.lang.VMThread for the main thread */
+
+ vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
+
+ if (vmt == NULL)
+ return false;
+
+ /* set the thread */
+
+ LLNI_field_set_ref(vmt, thread, t);
+ LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) mainthread);
+
+ /* call java.lang.Thread.<init>(Ljava/lang/VMThread;Ljava/lang/String;IZ)V */
+ o = (java_handle_t *) t;
+
+ (void) vm_call_method(method_thread_init, o, vmt, threadname, NORM_PRIORITY,
+ false);
+
+#elif defined(WITH_CLASSPATH_SUN)
+
+ /* We trick java.lang.Thread.init, which sets the priority of the
+ current thread to the parent's one. */
+
+ t->priority = NORM_PRIORITY;
+
+#elif defined(WITH_CLASSPATH_CLDC1_1)
+
+ /* set the thread */
+
+ t->vm_thread = (java_lang_Object *) mainthread;
+
+ /* call public Thread(String name) */
+
+ o = (java_handle_t *) t;
+
+ (void) vm_call_method(method_thread_init, o, threadname);
+#else
+# error unknown classpath configuration
+#endif
+
+ if (exceptions_get_exception())
+ return false;
+
+#if defined(ENABLE_JAVASE)
+ LLNI_field_set_ref(t, group, threadgroup);
+
+# if defined(WITH_CLASSPATH_GNU)
+ /* add main thread to java.lang.ThreadGroup */
+
+ m = class_resolveclassmethod(class_java_lang_ThreadGroup,
+ utf_addThread,
+ utf_java_lang_Thread__V,
+ class_java_lang_ThreadGroup,
+ true);
+
+ o = (java_handle_t *) threadgroup;
+
+ (void) vm_call_method(m, o, t);
+
+ if (exceptions_get_exception())
+ return false;
+# else
+# warning Do not know what to do here
+# endif
+#endif
+
+ threads_set_thread_priority(pthread_self(), NORM_PRIORITY);
+
+ /* initialize the thread attribute object */
+
+ if (pthread_attr_init(&attr) != 0)
+ vm_abort("threads_init: pthread_attr_init failed: %s", strerror(errno));
+
+ if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
+ vm_abort("threads_init: pthread_attr_setdetachstate failed: %s",
+ strerror(errno));
+
+#if !defined(NDEBUG)
+ if (opt_verbosethreads) {
+ printf("[Starting thread ");
+ threads_thread_print_info(mainthread);
+ printf("]\n");
+ }
+#endif
+
+ /* everything's ok */
+
+ return true;
+}
+
+
+/* threads_startup_thread ******************************************************