+ /* table[0] serves as the head of the freelist */
+
+ index = threads_table.table[0].nextfree;
+
+ /* if we got a free index, use it */
+
+ if (index) {
+got_an_index:
+ threads_table.table[0].nextfree = threads_table.table[index].nextfree;
+ threads_table.table[index].thread = thread;
+ thread->index = index;
+ thread->thinlock = lock_pre_compute_thinlock(index);
+ return index;
+ }
+
+ /* we must grow the table */
+
+ oldsize = threads_table.size;
+ newsize = oldsize * 2;
+
+ threads_table.table = MREALLOC(threads_table.table, threads_table_entry_t,
+ oldsize, newsize);
+ threads_table.size = newsize;
+
+ /* link the new entries to a free list */
+
+ for (i=oldsize; i<newsize; ++i) {
+ threads_table.table[i].nextfree = i+1;
+ }
+
+ /* terminate the freelist */
+
+ threads_table.table[newsize-1].nextfree = 0; /* index 0 is never free */
+
+ /* use the first of the new entries */
+
+ index = oldsize;
+ goto got_an_index;
+}
+
+
+/* threads_table_remove *******************************************************
+
+ Remove a thread from the global threads table.
+
+ IN:
+ thread............the thread to remove
+
+ PRE-CONDITION:
+ The caller must hold the threadlistlock!
+
+******************************************************************************/
+
+static void threads_table_remove(threadobject *thread)
+{
+ s4 index;
+
+ index = thread->index;
+
+ /* put the index into the freelist */
+
+ threads_table.table[index] = threads_table.table[0];
+ threads_table.table[0].nextfree = index;
+
+ /* delete the index in the threadobject to discover bugs */
+#if !defined(NDEBUG)
+ thread->index = 0;
+#endif
+}
+
+
+/* threads_startup_thread ******************************************************
+
+ Thread startup function called by pthread_create.
+
+ Thread which have a startup.function != NULL are marked as internal
+ threads. All other threads are threated as normal Java threads.
+
+ NOTE: This function is not called directly by pthread_create. The Boehm GC
+ inserts its own GC_start_routine in between, which then calls
+ threads_startup.
+
+ IN:
+ t............the argument passed to pthread_create, ie. a pointer to
+ a startupinfo struct. CAUTION: When the `psem` semaphore
+ is posted, the startupinfo struct becomes invalid! (It
+ is allocated on the stack of threads_start_thread.)
+
+******************************************************************************/
+
+static void *threads_startup_thread(void *t)
+{
+ startupinfo *startup;
+ threadobject *thread;
+#if defined(WITH_CLASSPATH_GNU)
+ java_lang_VMThread *vmt;
+#endif
+ sem_t *psem;
+ threadobject *tnext;
+ classinfo *c;
+ methodinfo *m;
+ java_objectheader *o;
+ functionptr function;
+
+#if defined(ENABLE_INTRP)