* src/threads/threadlist.c: New file.
authorChristian Thalinger <twisti@complang.tuwien.ac.at>
Wed, 5 Mar 2008 14:17:34 +0000 (15:17 +0100)
committerChristian Thalinger <twisti@complang.tuwien.ac.at>
Wed, 5 Mar 2008 14:17:34 +0000 (15:17 +0100)
* src/threads/threadlist.h: Likewise.

* src/threads/Makefile.am (libthreads_la_SOURCES): Added
threadlist.[ch].

* src/threads/lock-common.h: Changed copyright.

* src/threads/native/lock.c (threads/threadlist.h): Added.
(threads_lookup_thread_id): Use threadlist_* functions.

* src/threads/native/threads.c (threads/threadlist.h): Added.
(threads_cast_sendsignals): Use threadlist_* functions.
(threads_stopworld): Likewise.
(threads_startworld): Likewise.
(threads_init): Likewise.
(threads_attach_current_thread): Likewise.
(threads_join_all_threads): Likewise.

* src/threads/threads-common.c (threads/threadlist.h): Added.
(list_threads, list_free_threads, list_free_thread_index): Removed.
(thread_index_t): Removed.
(threads_preinit): Don't initialize the thread lists, moved
lock_init and critical_init calls into vm_create.
(threads_list_first, threads_list_next): Removed.
(threads_list_get_non_daemons): Likewise.
(threads_thread_new, threads_thread_free): Use threadlist_* functions.

* src/threads/threads-common.h (threads_list_first): Removed.
(threads_list_next): Likewise.
(threads_list_get_non_daemons): Likewise.

* src/vm/vm.c (threads/lock-common.h): Added.
(threads/threadlist.h): Added.
(vm_create) [ENABLE_THREADS]: Call threadlist_init, lock_init and
critical_init.

src/threads/Makefile.am
src/threads/lock-common.h
src/threads/native/lock.c
src/threads/native/threads.c
src/threads/threadlist.c [new file with mode: 0644]
src/threads/threadlist.h [new file with mode: 0644]
src/threads/threads-common.c
src/threads/threads-common.h
src/vm/vm.c

index 9ef68cfb57debb621b491f136d0fc1fa487e196d..29f3701cf168101899a00fc336a87d7787ffbd91 100644 (file)
@@ -1,9 +1,7 @@
 ## src/threads/Makefile.am
 ##
-## Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
-## C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-## E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-## J. Wenninger, Institut f. Computersprachen - TU Wien
+## Copyright (C) 1996-2005, 2006, 2007, 2008
+## CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 ##
 ## This file is part of CACAO.
 ##
@@ -44,6 +42,8 @@ libthreads_la_SOURCES = \
        critical.c \
        critical.h \
        lock-common.h \
+       threadlist.c \
+       threadlist.h \
        threads-common.c \
        threads-common.h
 
index 8d7edb6772aa8b136baba098df537668d13ef4de..35fc0e60746c71a8cc3364d8321c64ffc5ea632c 100644 (file)
@@ -1,9 +1,7 @@
 /* src/threads/lock-common.h - common stuff of lock implementation
 
-   Copyright (C) 2007 R. Grafl, A. Krall, C. Kruegel,
-   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-   J. Wenninger, Institut f. Computersprachen - TU Wien
+   Copyright (C) 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
index 6bcc20294e84070f1cf89bdbe2216ab28c22088e..e7b2744ba62773841d4d14323e44470101ee9f9d 100644 (file)
@@ -39,6 +39,7 @@
 #include "native/llni.h"
 
 #include "threads/lock-common.h"
+#include "threads/threadlist.h"
 #include "threads/threads-common.h"
 
 #include "threads/native/lock.h"
@@ -829,7 +830,7 @@ static threadobject *threads_lookup_thread_id(int index)
 
        threads_list_lock();
 
-       for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
+       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
                if (t->state == THREAD_STATE_NEW)
                        continue;
                if (t->index == index)
index f63abbfd638435170b7fa4d294255dca04ac9a03..687ef3ddac137c61e6cd621bcd59692a683a8e4d 100644 (file)
@@ -73,6 +73,7 @@
 #endif
 
 #include "threads/lock-common.h"
+#include "threads/threadlist.h"
 #include "threads/threads-common.h"
 
 #include "threads/native/threads.h"
@@ -396,7 +397,7 @@ static s4 threads_cast_sendsignals(s4 sig)
 
        count = 0;
 
-       for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
+       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
                /* don't send the signal to ourself */
 
                if (t == self)
@@ -568,7 +569,7 @@ void threads_stopworld(void)
        count = 0;
 
        /* suspend all running threads */
-       for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
+       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
                /* don't send the signal to ourself */
 
                if (t == self)
@@ -634,7 +635,7 @@ void threads_startworld(void)
        count = 0;
 
        /* resume all thread we haltet */
-       for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
+       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
                /* don't send the signal to ourself */
 
                if (t == self)
@@ -1107,7 +1108,7 @@ bool threads_init(void)
        /* Get the main-thread (NOTE: The main threads is always the first
           thread in the list). */
 
-       mainthread = threads_list_first();
+       mainthread = threadlist_first();
 
        /* create a java.lang.Thread for the main thread */
 
@@ -1629,7 +1630,7 @@ bool threads_attach_current_thread(JavaVMAttachArgs *vm_aargs, bool isdaemon)
 #if defined(ENABLE_JAVASE)
                /* get the main thread */
 
-               mainthread = threads_list_first();
+               mainthread = threadlist_first();
                mainthreado = (java_lang_Thread *) threads_thread_get_object(mainthread);
                LLNI_field_get_ref(mainthreado, group, group);
 #endif
@@ -1977,7 +1978,7 @@ void threads_join_all_threads(void)
           compare against 1 because the current (main thread) is also a
           non-daemon thread. */
 
-       while (threads_list_get_non_daemons() > 1)
+       while (threadlist_get_non_daemons() > 1)
                pthread_cond_wait(&cond_join, &mutex_join);
 
        /* leave join mutex */
diff --git a/src/threads/threadlist.c b/src/threads/threadlist.c
new file mode 100644 (file)
index 0000000..c401ff1
--- /dev/null
@@ -0,0 +1,339 @@
+/* src/threads/threadlist.c - different thread-lists
+
+   Copyright (C) 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "mm/memory.h"
+
+#include "threads/threadlist.h"
+#include "threads/threads-common.h"
+
+#include "toolbox/list.h"
+
+#include "vmcore/options.h"
+
+
+/* global variables ***********************************************************/
+
+static list_t *list_thread;                            /* global threads list */
+static list_t *list_thread_free;                  /* global free threads list */
+static list_t *list_thread_index_free;
+
+
+typedef struct thread_index_t {
+       int32_t    index;
+       listnode_t linkage;
+} thread_index_t;
+
+
+/* threadlist_init *************************************************************
+
+   Initialize thread-lists.
+
+*******************************************************************************/
+
+void threadlist_init(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("threadlist_init");
+
+       /* Initialize the thread lists. */
+
+       list_thread            = list_create(OFFSET(threadobject, linkage));
+       list_thread_free       = list_create(OFFSET(threadobject, linkage_free));
+       list_thread_index_free = list_create(OFFSET(thread_index_t, linkage));
+}
+
+
+/* threadlist_add **************************************************************
+
+   Add the given threadobject as last entry to the thread list.
+
+   IN:
+       t ... threadobject to be added
+
+*******************************************************************************/
+
+void threadlist_add(threadobject *t)
+{
+       list_add_last_unsynced(list_thread, t);
+}
+
+
+/* threadlist_remove ***********************************************************
+
+   Remove the given threadobject from the thread list.
+
+   IN:
+       t ... threadobject to be removed
+
+*******************************************************************************/
+
+void threadlist_remove(threadobject *t)
+{
+       list_remove_unsynced(list_thread, t);
+}
+
+
+/* threadlist_first ************************************************************
+
+   Return the first entry in the thread list.
+
+   RETURN:
+       threadobject of the first entry
+
+*******************************************************************************/
+
+threadobject *threadlist_first(void)
+{
+       threadobject *t;
+
+       t = list_first_unsynced(list_thread);
+
+       return t;
+}
+
+
+/* threads_list_next ***********************************************************
+
+   Return the next entry in the thread list.
+
+   IN:
+       t ... threadobject to get next thread of
+
+   RETURN:
+       threadobject of the next entry
+
+*******************************************************************************/
+
+threadobject *threadlist_next(threadobject *t)
+{
+       threadobject *next;
+
+       next = list_next_unsynced(list_thread, t);
+
+       return next;
+}
+
+
+/* threadlist_free_add *********************************************************
+
+   Add the given threadobject as last entry to the free thread list.
+
+   IN:
+       t ... threadobject to be added
+
+*******************************************************************************/
+
+void threadlist_free_add(threadobject *t)
+{
+       list_add_last_unsynced(list_thread_free, t);
+}
+
+
+/* threadlist_free_remove ******************************************************
+
+   Remove the given entry from the free thread list.
+
+   IN:
+       t ... threadobject to be removed
+
+*******************************************************************************/
+
+void threadlist_free_remove(threadobject *t)
+{
+       list_remove_unsynced(list_thread_free, t);
+}
+
+
+/* threadlist_free_first *******************************************************
+
+   Return the first entry in the free thread list.
+
+   RETURN:
+       threadobject of the first free entry
+
+*******************************************************************************/
+
+threadobject *threadlist_free_first(void)
+{
+       threadobject *t;
+
+       t = list_first_unsynced(list_thread_free);
+
+       return t;
+}
+
+
+/* threadlist_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.
+
+*******************************************************************************/
+
+int threadlist_get_non_daemons(void)
+{
+       threadobject *t;
+       int           nondaemons;
+
+       /* Lock the threads lists. */
+
+       threads_list_lock();
+
+       nondaemons = 0;
+
+       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
+               if (!(t->flags & THREAD_FLAG_DAEMON))
+                       nondaemons++;
+       }
+
+       /* Unlock the threads lists. */
+
+       threads_list_unlock();
+
+       return nondaemons;
+}
+
+
+/* threadlist_index_first ******************************************************
+
+   Return the first entry in the thread-index list.
+
+   RETURN VALUE:
+       thread-index structure
+
+*******************************************************************************/
+
+static inline thread_index_t *threadlist_index_first(void)
+{
+       thread_index_t *ti;
+
+       ti = list_first_unsynced(list_thread_index_free);
+
+       return ti;
+}
+
+
+/* threadlist_index_add ********************************************************
+
+   Add the given thread-index to the thread-index free list.
+
+   IN:
+       i ... thread index
+
+*******************************************************************************/
+
+void threadlist_index_add(int index)
+{
+       thread_index_t *ti;
+
+       ti = NEW(thread_index_t);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               size_thread_index_t += sizeof(thread_index_t);
+#endif
+
+       list_add_last_unsynced(list_thread_index_free, ti);
+}
+
+
+/* threadlist_index_remove *****************************************************
+
+   Remove the given thread-index from the thread-index list and free
+   the thread-index structure.
+
+   IN:
+       ti ... thread-index structure
+
+*******************************************************************************/
+
+static inline void threadlist_index_remove(thread_index_t *ti)
+{
+       list_remove_unsynced(list_thread_index_free, ti);
+
+       FREE(ti, thread_index_t);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               size_thread_index_t -= sizeof(thread_index_t);
+#endif
+}
+
+
+/* threadlist_get_free_index ***************************************************
+
+   Return a free thread index.
+
+   RETURN VALUE:
+       free thread index
+
+*******************************************************************************/
+
+int threadlist_get_free_index(void)
+{
+       thread_index_t *ti;
+       int             index;
+
+       /* Try to get a thread index from the free-list. */
+
+       ti = threadlist_index_first();
+
+       /* Is a free thread index available? */
+
+       if (ti != NULL) {
+               /* Yes, get the index and remove it from the free list. */
+
+               index = ti->index;
+
+               threadlist_index_remove(ti);
+       }
+       else {
+               /* Get a new the thread index. */
+
+               index = list_thread->size + 1;
+       }
+
+       return index;
+}
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/threads/threadlist.h b/src/threads/threadlist.h
new file mode 100644 (file)
index 0000000..a76bfde
--- /dev/null
@@ -0,0 +1,69 @@
+/* src/threads/threadlist.h - different thread-lists
+
+   Copyright (C) 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#ifndef _THREADLIST_H
+#define _THREADLIST_H
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "threads/threads-common.h"
+
+
+/* function prototypes ********************************************************/
+
+void          threadlist_init(void);
+
+void          threadlist_add(threadobject *t);
+void          threadlist_remove(threadobject *t);
+threadobject *threadlist_first(void);
+threadobject *threadlist_next(threadobject *t);
+
+void          threadlist_free_add(threadobject *t);
+void          threadlist_free_remove(threadobject *t);
+threadobject *threadlist_free_first(void);
+
+int           threadlist_get_non_daemons(void);
+
+void          threadlist_index_add(int index);
+int           threadlist_get_free_index(void);
+
+#endif /* _THREADLIST_H */
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
index 9acfa5e83744ce3a46f5247a75427eb1f86305c6..8b00e663b94a4b6f6347fe3c800ee9e93758d45a 100644 (file)
@@ -47,6 +47,7 @@
 
 #include "threads/critical.h"
 #include "threads/lock-common.h"
+#include "threads/threadlist.h"
 #include "threads/threads-common.h"
 
 #include "toolbox/list.h"
 
 /* global variables ***********************************************************/
 
-/* global threads list */
-static list_t *list_threads;
-/* global free threads list */
-static list_t *list_free_threads;
-
-/* global threads free-list */
-
-typedef struct thread_index_t {
-       int32_t    index;
-       listnode_t linkage;
-} thread_index_t;
-
-static list_t *list_free_thread_index;
-
 #if defined(__LINUX__)
 /* XXX Remove for exact-GC. */
 bool threads_pthreads_implementation_nptl;
@@ -93,9 +80,6 @@ bool threads_pthreads_implementation_nptl;
 
    Do some early initialization of stuff required.
 
-   ATTENTION: Do NOT use any Java heap allocation here, as gc_init()
-   is called AFTER this function!
-
 *******************************************************************************/
 
 void threads_preinit(void)
@@ -140,12 +124,6 @@ void threads_preinit(void)
 # endif
 #endif
 
-       /* initialize the threads lists */
-
-       list_threads           = list_create(OFFSET(threadobject, linkage));
-       list_free_threads      = list_create(OFFSET(threadobject, linkage_free));
-       list_free_thread_index = list_create(OFFSET(thread_index_t, linkage));
-
        /* Initialize the threads implementation (sets the thinlock on the
           main thread). */
 
@@ -163,83 +141,6 @@ void threads_preinit(void)
        /* store the internal thread data-structure in the TSD */
 
        threads_set_current_threadobject(mainthread);
-
-       /* initialize locking subsystems */
-
-       lock_init();
-
-       /* initialize the critical section */
-
-       critical_init();
-}
-
-
-/* threads_list_first **********************************************************
-
-   Return the first entry in the threads list.
-
-   NOTE: This function does not lock the lists.
-
-*******************************************************************************/
-
-threadobject *threads_list_first(void)
-{
-       threadobject *t;
-
-       t = list_first_unsynced(list_threads);
-
-       return t;
-}
-
-
-/* threads_list_next ***********************************************************
-
-   Return the next entry in the threads list.
-
-   NOTE: This function does not lock the lists.
-
-*******************************************************************************/
-
-threadobject *threads_list_next(threadobject *t)
-{
-       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;
 }
 
 
@@ -252,7 +153,6 @@ s4 threads_list_get_non_daemons(void)
 
 threadobject *threads_thread_new(void)
 {
-       thread_index_t *ti;
        int32_t         index;
        threadobject   *t;
        
@@ -260,42 +160,21 @@ threadobject *threads_thread_new(void)
 
        threads_list_lock();
 
-       /* Try to get a thread index from the free-list. */
-
-       ti = list_first_unsynced(list_free_thread_index);
-
-       /* Is a free thread index available? */
-
-       if (ti != NULL) {
-               /* Yes, remove it from the free list, get the index and free
-                  the entry. */
-
-               list_remove_unsynced(list_free_thread_index, ti);
-
-               index = ti->index;
-
-               FREE(ti, thread_index_t);
-
-#if defined(ENABLE_STATISTICS)
-               if (opt_stat)
-                       size_thread_index_t -= sizeof(thread_index_t);
-#endif
-       }
-       else {
-               /* Get a new the thread index. */
-
-               index = list_threads->size + 1;
-       }
+       index = threadlist_get_free_index();
 
        /* Allocate a thread data structure. */
 
        /* First, try to get one from the free-list. */
-       t = list_first_unsynced(list_free_threads);
+
+       t = threadlist_free_first();
+
        if (t != NULL) {
                /* Remove from free list. */
-               list_remove_unsynced(list_free_threads, t);
+
+               threadlist_free_remove(t);
 
                /* Equivalent of MZERO on the else path */
+
                threads_impl_thread_clear(t);
        }
        else {
@@ -344,9 +223,9 @@ threadobject *threads_thread_new(void)
 
        threads_impl_thread_reuse(t);
 
-       /* Add the thread to the threads-list. */
+       /* Add the thread to the thread list. */
 
-       list_add_last_unsynced(list_threads, t);
+       threadlist_add(t);
 
        /* Unlock the threads-lists. */
 
@@ -369,34 +248,23 @@ threadobject *threads_thread_new(void)
 
 void threads_thread_free(threadobject *t)
 {
-       thread_index_t *ti;
-
        /* Lock the threads lists. */
 
        threads_list_lock();
 
-       /* Remove the thread from the threads-list. */
+       /* Remove the thread from the thread-list. */
 
-       list_remove_unsynced(list_threads, t);
+       threadlist_remove(t);
 
        /* Add the thread index to the free list. */
 
-       ti = NEW(thread_index_t);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               size_thread_index_t += sizeof(thread_index_t);
-#endif
-
-       ti->index = t->index;
-
-       list_add_last_unsynced(list_free_thread_index, ti);
+       threadlist_index_add(t->index);
 
        /* Add the thread data structure to the free list. */
 
        threads_thread_set_object(t, NULL);
 
-       list_add_last_unsynced(list_free_threads, t);
+       threadlist_free_add(t);
 
        /* Unlock the threads lists. */
 
@@ -850,7 +718,7 @@ void threads_dump(void)
 
        /* iterate over all started threads */
 
-       for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
+       for (t = threadlist_first(); t != NULL; t = threadlist_next(t)) {
                /* ignore threads which are in state NEW */
                if (t->state == THREAD_STATE_NEW)
                        continue;
index e1ee59db78d9fbbe50752007fbc292df702e26cb..4d0ce24e8a30b0835e2bee68ea12c72b022d8bb0 100644 (file)
@@ -115,10 +115,6 @@ static inline void threads_thread_set_object(threadobject *t, java_handle_t *obj
 
 void          threads_preinit(void);
 
-threadobject *threads_list_first(void);
-threadobject *threads_list_next(threadobject *t);
-s4            threads_list_get_non_daemons(void);
-
 threadobject *threads_thread_new(void);
 void          threads_thread_free(threadobject *t);
 
index 799c8421ecdbcb51ae3143e4b06f957215d4aa82..d9641b9670f0f8dffb7319ccabf4d06d3090a2ea 100644 (file)
@@ -58,6 +58,8 @@
 
 #include "native/vm/nativevm.h"
 
+#include "threads/lock-common.h"
+#include "threads/threadlist.h"
 #include "threads/threads-common.h"
 
 #include "toolbox/logging.h"
@@ -1407,10 +1409,16 @@ bool vm_create(JavaVMInitArgs *vm_args)
        gc_init(opt_heapmaxsize, opt_heapstartsize);
 
 #if defined(ENABLE_THREADS)
+       /* BEFORE: threads_preinit */
+
+       threadlist_init();
+
        /* AFTER: gc_init (directly after, as this initializes the
           stopworldlock lock */
 
        threads_preinit();
+       lock_init();
+       critical_init();
 #endif
 
        /* install architecture dependent signal handlers */