Reusing threadobjects.
authorStefan Ring <stefan@complang.tuwien.ac.at>
Fri, 29 Feb 2008 11:27:16 +0000 (12:27 +0100)
committerStefan Ring <stefan@complang.tuwien.ac.at>
Fri, 29 Feb 2008 11:27:16 +0000 (12:27 +0100)
* src/threads/native/threads.c (threads_impl_thread_new): Removed and split
up into three new functions.
(threads_impl_thread_init, threads_impl_thread_clear)
(threads_impl_thread_reuse): New functions.
(threads_impl_thread_free): Disabled.

* src/threads/native/threads.h (threadobject): Added field for free-list.

* src/threads/threads-common.c (threads_preinit, threads_thread_new)
(threads_thread_free): Reuse threadobjects.

* src/threads/threads-common.h: New function declarations.

src/threads/native/threads.c
src/threads/native/threads.h
src/threads/threads-common.c
src/threads/threads-common.h

index 1b134fa10327d65c1a488c6310dcd522c1b0f710..ce18dfecd3b753477bbe1b0edf5bf708f9a0a098 100644 (file)
@@ -691,23 +691,19 @@ void threads_set_current_threadobject(threadobject *thread)
 }
 
 
-/* threads_impl_thread_new *****************************************************
+/* threads_impl_thread_init ****************************************************
 
-   Initialize implementation fields of a threadobject.
+   Initialize OS-level locking constructs in threadobject.
 
    IN:
       t....the threadobject
 
 *******************************************************************************/
 
-void threads_impl_thread_new(threadobject *t)
+void threads_impl_thread_init(threadobject *t)
 {
        int result;
 
-       /* get the pthread id */
-
-       t->tid = pthread_self();
-
        /* initialize the mutex and the condition */
 
        result = pthread_mutex_init(&t->flc_lock, NULL);
@@ -733,6 +729,77 @@ void threads_impl_thread_new(threadobject *t)
        result = pthread_cond_init(&(t->suspendcond), NULL);
        if (result != 0)
                vm_abort_errnum(result, "threads_impl_thread_new: pthread_cond_init failed");
+}
+
+/* threads_impl_thread_clear ***************************************************
+
+   Clears all fields in threadobject the way an MZERO would have
+   done. MZERO cannot be used anymore because it would mess up the
+   pthread_* bits.
+
+   IN:
+      t....the threadobject
+
+*******************************************************************************/
+
+void threads_impl_thread_clear(threadobject *t)
+{
+       t->object = NULL;
+
+       t->thinlock = 0;
+
+       t->index = 0;
+       t->flags = 0;
+       t->state = 0;
+
+       t->tid = 0;
+
+#if defined(__DARWIN__)
+       t->mach_thread = 0;
+#endif
+
+       t->interrupted = false;
+       t->signaled = false;
+       t->sleeping = false;
+
+       t->suspended = false;
+       t->suspend_reason = 0;
+
+       t->pc = NULL;
+
+       t->_exceptionptr = NULL;
+       t->_stackframeinfo = NULL;
+       t->_localref_table = NULL;
+
+#if defined(ENABLE_INTRP)
+       t->_global_sp = NULL;
+#endif
+
+#if defined(ENABLE_GC_CACAO)
+       t->gc_critical = false;
+
+       t->ss = NULL;
+       t->es = NULL;
+#endif
+
+       MZERO(&t->dumpinfo, dumpinfo_t, 1);
+}
+
+/* threads_impl_thread_reuse ***************************************************
+
+   Resets some implementation fields in threadobject. This was
+   previously done in threads_impl_thread_new.
+
+   IN:
+      t....the threadobject
+
+*******************************************************************************/
+
+void threads_impl_thread_reuse(threadobject *t)
+{
+       /* get the pthread id */
+
+       t->tid = pthread_self();
 
 #if defined(ENABLE_DEBUG_FILTER)
        /* Initialize filter counters */
@@ -763,6 +830,8 @@ void threads_impl_thread_new(threadobject *t)
 
 *******************************************************************************/
 
+#if 0
+/* never used */
 void threads_impl_thread_free(threadobject *t)
 {
        int result;
@@ -799,6 +868,7 @@ void threads_impl_thread_free(threadobject *t)
        if (result != 0)
                vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
 }
+#endif
 
 
 /* threads_get_current_threadobject ********************************************
index fd2ee45b953ae03c217bac60c7eced58797fb8b9..ed523f65b5760cd664dff8bacf1d8781e5540faa 100644 (file)
@@ -171,6 +171,7 @@ struct threadobject {
 #endif
 
        listnode_t            linkage;      /* threads-list                       */
+       listnode_t            linkage_free; /* free-list                          */
 };
 
 
index 34622e1d0146819effd687f05bd5f1b7e4777f34..9acfa5e83744ce3a46f5247a75427eb1f86305c6 100644 (file)
@@ -71,6 +71,8 @@
 
 /* global threads list */
 static list_t *list_threads;
+/* global free threads list */
+static list_t *list_free_threads;
 
 /* global threads free-list */
 
@@ -141,6 +143,7 @@ void threads_preinit(void)
        /* 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
@@ -286,28 +289,44 @@ threadobject *threads_thread_new(void)
 
        /* Allocate a thread data structure. */
 
+       /* First, try to get one from the free-list. */
+       t = list_first_unsynced(list_free_threads);
+       if (t != NULL) {
+               /* Remove from free list. */
+               list_remove_unsynced(list_free_threads, t);
+
+               /* Equivalent of MZERO on the else path */
+               threads_impl_thread_clear(t);
+       }
+       else {
 #if defined(ENABLE_GC_BOEHM)
-       t = GCNEW_UNCOLLECTABLE(threadobject, 1);
+               t = GCNEW_UNCOLLECTABLE(threadobject, 1);
 #else
-       t = NEW(threadobject);
+               t = NEW(threadobject);
 #endif
 
 #if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               size_threadobject += sizeof(threadobject);
+               if (opt_stat)
+                       size_threadobject += sizeof(threadobject);
 #endif
 
-       /* Clear memory. */
+               /* Clear memory. */
 
-       MZERO(t, threadobject, 1);
+               MZERO(t, threadobject, 1);
 
 #if defined(ENABLE_GC_CACAO)
-       /* Register reference to java.lang.Thread with the GC. */
+               /* Register reference to java.lang.Thread with the GC. */
+               /* FIXME is it ok to do this only once? */
 
-       gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
-       gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
+               gc_reference_register(&(t->object), GC_REFTYPE_THREADOBJECT);
+               gc_reference_register(&(t->_exceptionptr), GC_REFTYPE_THREADOBJECT);
 #endif
 
+               /* Initialize the implementation-specific bits. */
+
+               threads_impl_thread_init(t);
+       }
+
        /* Pre-compute the thinlock-word. */
 
        assert(index != 0);
@@ -323,7 +342,7 @@ threadobject *threads_thread_new(void)
 
        /* Initialize the implementation-specific bits. */
 
-       threads_impl_thread_new(t);
+       threads_impl_thread_reuse(t);
 
        /* Add the thread to the threads-list. */
 
@@ -356,10 +375,6 @@ void threads_thread_free(threadobject *t)
 
        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);
@@ -377,18 +392,11 @@ void threads_thread_free(threadobject *t)
 
        list_add_last_unsynced(list_free_thread_index, ti);
 
-       /* Free the thread data structure. */
+       /* Add the thread data structure to the free list. */
 
-#if defined(ENABLE_GC_BOEHM)
-       GCFREE(t);
-#else
-       FREE(t, threadobject);
-#endif
+       threads_thread_set_object(t, NULL);
 
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               size_threadobject -= sizeof(threadobject);
-#endif
+       list_add_last_unsynced(list_free_threads, t);
 
        /* Unlock the threads lists. */
 
index 6a1ad65c5307b98392322f89ef0e9bfe5fdda81e..e1ee59db78d9fbbe50752007fbc292df702e26cb 100644 (file)
@@ -158,7 +158,9 @@ void          threads_mutex_join_lock(void);
 void          threads_mutex_join_unlock(void);
 
 void          threads_set_current_threadobject(threadobject *thread);
-void          threads_impl_thread_new(threadobject *t);
+void          threads_impl_thread_init(threadobject *t);
+void          threads_impl_thread_clear(threadobject *t);
+void          threads_impl_thread_reuse(threadobject *t);
 void          threads_impl_thread_free(threadobject *t);
 void          threads_impl_thread_start(threadobject *thread, functionptr f);