Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: threads-common.c 7963 2007-05-24 10:21:16Z twisti $
-
*/
#include "config.h"
#include <assert.h>
+#include <stdint.h>
+#include <unistd.h>
#include "vm/types.h"
#include "mm/memory.h"
#include "native/jni.h"
+#include "native/llni.h"
#include "native/include/java_lang_Object.h"
#include "native/include/java_lang_String.h"
/* global threads free-list */
static list_t *list_threads_free;
+#if defined(__LINUX__)
+/* XXX Remove for exact-GC. */
+bool threads_pthreads_implementation_nptl;
+#endif
+
/* threads_preinit *************************************************************
void threads_preinit(void)
{
threadobject *mainthread;
+#if defined(__LINUX__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
+ char *pathbuf;
+ size_t len;
+#endif
+
+#if defined(__LINUX__)
+ /* XXX Remove for exact-GC. */
+
+ /* On Linux we need to check the pthread implementation. */
+
+ /* _CS_GNU_LIBPTHREAD_VERSION (GNU C library only; since glibc 2.3.2) */
+ /* If the glibc is a pre-2.3.2 version, we fall back to
+ linuxthreads. */
+
+# if defined(_CS_GNU_LIBPTHREAD_VERSION)
+ len = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, (size_t) 0);
+
+ /* Some systems return as length 0 (maybe cross-compilation
+ related). In this case we also fall back to linuxthreads. */
+
+ if (len > 0) {
+ pathbuf = MNEW(char, len);
+
+ (void) confstr(_CS_GNU_LIBPTHREAD_VERSION, pathbuf, len);
+
+ if (strstr(pathbuf, "NPTL") != NULL)
+ threads_pthreads_implementation_nptl = true;
+ else
+ threads_pthreads_implementation_nptl = false;
+ }
+ else
+ threads_pthreads_implementation_nptl = false;
+# else
+ threads_pthreads_implementation_nptl = false;
+# endif
+#endif
/* initialize the threads lists */
void threads_thread_free(threadobject *t)
{
- s4 index;
+ int32_t index;
+ uint32_t state;
/* lock the threads-lists */
list_remove_unsynced(list_threads, t);
- /* Clear memory, but keep the thread-index. */
+ /* Clear memory, but keep the thread-index and the
+ thread-state. */
+
/* ATTENTION: Do this after list_remove, otherwise the linkage
pointers are invalid. */
index = t->index;
+ state = t->state;
MZERO(t, threadobject, 1);
t->index = index;
+ t->state = state;
/* add the thread to the free list */
bool threads_thread_start_internal(utf *name, functionptr f)
{
- threadobject *thread;
- java_lang_Thread *t;
+ threadobject *t;
+ java_lang_Thread *object;
#if defined(WITH_CLASSPATH_GNU)
java_lang_VMThread *vmt;
#endif
+ /* Enter the join-mutex, so if the main-thread is currently
+ waiting to join all threads, the number of non-daemon threads
+ is correct. */
+
+ threads_mutex_join_lock();
+
/* create internal thread data-structure */
- thread = threads_thread_new();
+ t = threads_thread_new();
+
+ t->flags = THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
+
+ /* The thread is flagged as (non-)daemon thread, we can leave the
+ mutex. */
+
+ threads_mutex_join_unlock();
/* create the java thread object */
- t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
+ object = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
- if (t == NULL)
+ /* XXX memory leak!!! */
+ if (object == NULL)
return false;
#if defined(WITH_CLASSPATH_GNU)
vmt = (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
+ /* XXX memory leak!!! */
if (vmt == NULL)
return false;
- vmt->thread = t;
- vmt->vmdata = (java_lang_Object *) thread;
+ LLNI_field_set_ref(vmt, thread, object);
+ LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) t);
- t->vmThread = vmt;
+ LLNI_field_set_ref(object, vmThread, vmt);
#elif defined(WITH_CLASSPATH_CLDC1_1)
- t->vm_thread = (java_lang_Object *) thread;
+ LLNI_field_set_val(object, vm_thread, (java_lang_Object *) t);
#endif
- thread->object = t;
-
- thread->flags = THREAD_FLAG_INTERNAL | THREAD_FLAG_DAEMON;
+ t->object = object;
/* set java.lang.Thread fields */
- t->name = (java_lang_String *) javastring_new(name);
+#if defined(WITH_CLASSPATH_GNU)
+ LLNI_field_set_ref(object, name , (java_lang_String *) javastring_new(name));
+#elif defined(WITH_CLASSPATH_CLDC1_1)
+ /* FIXME: In cldc the name is a char[] */
+/* LLNI_field_set_ref(object, name , (java_chararray *) javastring_new(name)); */
+ LLNI_field_set_ref(object, name , NULL);
+#endif
+
#if defined(ENABLE_JAVASE)
- t->daemon = true;
+ LLNI_field_set_val(object, daemon , true);
#endif
- t->priority = NORM_PRIORITY;
+
+ LLNI_field_set_val(object, priority, NORM_PRIORITY);
/* start the thread */
- threads_impl_thread_start(thread, f);
+ threads_impl_thread_start(t, f);
/* everything's ok */
void threads_thread_start(java_lang_Thread *object)
{
threadobject *thread;
+#if defined(WITH_CLASSPATH_GNU)
+ java_lang_VMThread *vmt;
+#endif
- /* create internal thread data-structure */
+ /* Enter the join-mutex, so if the main-thread is currently
+ waiting to join all threads, the number of non-daemon threads
+ is correct. */
- thread = threads_thread_new();
+ threads_mutex_join_lock();
- /* link the two objects together */
+ /* create internal thread data-structure */
- thread->object = object;
+ thread = threads_thread_new();
/* this is a normal Java thread */
#if defined(ENABLE_JAVASE)
/* is this a daemon thread? */
- if (object->daemon == true)
+ if (LLNI_field_direct(object, daemon) == true)
thread->flags |= THREAD_FLAG_DAEMON;
#endif
+ /* The thread is flagged and (non-)daemon thread, we can leave the
+ mutex. */
+
+ threads_mutex_join_unlock();
+
+ /* link the two objects together */
+
+ thread->object = object;
+
#if defined(WITH_CLASSPATH_GNU)
- assert(object->vmThread);
- assert(object->vmThread->vmdata == NULL);
+ LLNI_field_get_ref(object, vmThread, vmt);
+
+ assert(vmt);
+ assert(LLNI_field_direct(vmt, vmdata) == NULL);
- object->vmThread->vmdata = (java_lang_Object *) thread;
+ LLNI_field_set_val(vmt, vmdata, (java_lang_Object *) thread);
#elif defined(WITH_CLASSPATH_CLDC1_1)
- object->vm_thread = (java_lang_Object *) thread;
+ LLNI_field_set_val(object, vm_thread, (java_lang_Object *) thread);
#endif
/* Start the thread. Don't pass a function pointer (NULL) since
if (object != NULL) {
/* get thread name */
-#if defined(ENABLE_JAVASE)
- name = javastring_toutf((java_objectheader *) object->name, false);
-#elif defined(ENABLE_JAVAME_CLDC1_1)
- name = object->name;
+#if defined(WITH_CLASSPATH_GNU)
+ name = javastring_toutf((java_handle_t *) LLNI_field_direct(object, name), false);
+#elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
+ /* FIXME: In cldc the name is a char[] */
+/* name = object->name; */
+ name = utf_null;
+#else
+# error unknown classpath configuration
#endif
printf("\"");
if (t->flags & THREAD_FLAG_DAEMON)
printf(" daemon");
- printf(" prio=%d", object->priority);
+ printf(" prio=%d", LLNI_field_direct(object, priority));
#if SIZEOF_VOID_P == 8
printf(" t=0x%016lx tid=0x%016lx (%ld)",