}
-/* 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);
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 */
*******************************************************************************/
+#if 0
+/* never used */
void threads_impl_thread_free(threadobject *t)
{
int result;
if (result != 0)
vm_abort_errnum(result, "threads_impl_thread_free: pthread_cond_destroy failed");
}
+#endif
/* threads_get_current_threadobject ********************************************
/* global threads list */
static list_t *list_threads;
+/* global free threads list */
+static list_t *list_free_threads;
/* global threads free-list */
/* 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
/* 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);
/* Initialize the implementation-specific bits. */
- threads_impl_thread_new(t);
+ threads_impl_thread_reuse(t);
/* Add the thread to the threads-list. */
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);
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. */