+ threadobject *next;
+
+ next = list_next_unsynced(list_threads, t);
+
+ return next;
+}
+
+
+/* threads_list_get_non_daemons ************************************************
+
+ Return the number of non-daemon threads.
+
+ NOTE: This function does a linear-search over the threads list,
+ because it's only used for joining the threads.
+
+*******************************************************************************/
+
+s4 threads_list_get_non_daemons(void)
+{
+ threadobject *t;
+ s4 nondaemons;
+
+ /* lock the threads lists */
+
+ threads_list_lock();
+
+ nondaemons = 0;
+
+ for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
+ if (!(t->flags & THREAD_FLAG_DAEMON))
+ nondaemons++;
+ }
+
+ /* unlock the threads lists */
+
+ threads_list_unlock();
+
+ return nondaemons;
+}
+
+
+/* threads_thread_new **********************************************************
+
+ Allocates and initializes an internal thread data-structure and
+ adds it to the threads list.
+
+*******************************************************************************/
+
+threadobject *threads_thread_new(void)
+{
+ threadobject *t;
+
+ /* lock the threads-lists */
+
+ threads_list_lock();
+
+ /* try to get a thread from the free-list */
+
+ t = list_first_unsynced(list_threads_free);
+
+ /* is a free thread available? */
+
+ if (t != NULL) {
+ /* yes, remove it from the free list */
+
+ list_remove_unsynced(list_threads_free, t);
+ }
+ else {
+ /* no, allocate a new one */
+
+#if defined(ENABLE_GC_BOEHM)
+ t = GCNEW_UNCOLLECTABLE(threadobject, 1);
+#else
+ t = NEW(threadobject);
+#endif
+
+#if defined(ENABLE_STATISTICS)
+ if (opt_stat)
+ size_threadobject += sizeof(threadobject);
+#endif
+
+ /* clear memory */
+
+ MZERO(t, threadobject, 1);
+
+ /* set the threads-index */
+
+ t->index = list_threads->size + 1;
+ }
+
+ /* pre-compute the thinlock-word */
+
+ assert(t->index != 0);
+
+ t->thinlock = lock_pre_compute_thinlock(t->index);
+ t->state = THREAD_STATE_NEW;
+
+ /* initialize the implementation-specific bits */
+
+ threads_impl_thread_new(t);
+
+ /* add the thread to the threads-list */
+
+ list_add_last_unsynced(list_threads, t);
+
+ /* unlock the threads-lists */
+
+ threads_list_unlock();
+
+ return t;
+}
+
+
+/* threads_thread_free *********************************************************
+
+ Frees an internal thread data-structure by removing it from the
+ threads-list and adding it to the free-list.
+
+ NOTE: The data-structure is NOT freed, the pointer keeps valid!
+
+*******************************************************************************/
+
+void threads_thread_free(threadobject *t)
+{
+ int32_t index;
+ uint32_t state;
+
+ /* lock the threads-lists */
+
+ threads_list_lock();
+
+ /* cleanup the implementation-specific bits */
+
+ threads_impl_thread_free(t);
+
+ /* remove the thread from the threads-list */
+
+ list_remove_unsynced(list_threads, t);
+
+ /* Clear memory, but keep the thread-index and the
+ thread-state. */
+
+ /* ATTENTION: Do this after list_remove, otherwise the linkage
+ pointers are invalid. */
+
+ index = t->index;
+ state = t->state;
+
+ MZERO(t, threadobject, 1);
+
+ t->index = index;
+ t->state = state;
+
+ /* add the thread to the free list */
+
+ list_add_first_unsynced(list_threads_free, t);
+
+ /* unlock the threads-lists */
+
+ threads_list_unlock();
+}
+
+
+/* threads_thread_start_internal ***********************************************
+
+ Start an internal thread in the JVM. No Java thread objects exists
+ so far.
+
+ IN:
+ name.......UTF-8 name of the thread
+ f..........function pointer to C function to start
+
+*******************************************************************************/
+
+bool threads_thread_start_internal(utf *name, functionptr f)
+{
+ threadobject *t;
+ java_lang_Thread *object;