* 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
##
-## 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.
##
critical.c \
critical.h \
lock-common.h \
+ threadlist.c \
+ threadlist.h \
threads-common.c \
threads-common.h
/* 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.
#include "native/llni.h"
#include "threads/lock-common.h"
+#include "threads/threadlist.h"
#include "threads/threads-common.h"
#include "threads/native/lock.h"
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)
#endif
#include "threads/lock-common.h"
+#include "threads/threadlist.h"
#include "threads/threads-common.h"
#include "threads/native/threads.h"
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)
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)
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)
/* 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 */
#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
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 */
--- /dev/null
+/* 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:
+ */
--- /dev/null
+/* 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:
+ */
#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;
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)
# 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). */
/* 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;
}
threadobject *threads_thread_new(void)
{
- thread_index_t *ti;
int32_t index;
threadobject *t;
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 {
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. */
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. */
/* 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;
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);
#include "native/vm/nativevm.h"
+#include "threads/lock-common.h"
+#include "threads/threadlist.h"
#include "threads/threads-common.h"
#include "toolbox/logging.h"
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 */