X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fthreads%2Fthreads-common.c;h=89515056c98594f327eee75f526386e795cb11c2;hb=9f859ad50d3d5d98c185d40b86b2179bc4dc9aeb;hp=97d7aadfad6b676590c586fe365ae8abf3096a0e;hpb=e220e26c156e3af39585c68c1d2a3d9dbd7fe3e1;p=cacao.git diff --git a/src/threads/threads-common.c b/src/threads/threads-common.c index 97d7aadfa..89515056c 100644 --- a/src/threads/threads-common.c +++ b/src/threads/threads-common.c @@ -22,20 +22,21 @@ 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 +#include +#include #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" @@ -75,6 +76,11 @@ static list_t *list_threads; /* 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 ************************************************************* @@ -88,6 +94,42 @@ static list_t *list_threads_free; 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 */ @@ -274,7 +316,8 @@ threadobject *threads_thread_new(void) void threads_thread_free(threadobject *t) { - s4 index; + int32_t index; + uint32_t state; /* lock the threads-lists */ @@ -288,15 +331,19 @@ void threads_thread_free(threadobject *t) 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 */ @@ -321,52 +368,73 @@ void threads_thread_free(threadobject *t) 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 */ @@ -387,14 +455,19 @@ bool threads_thread_start_internal(utf *name, functionptr f) 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 */ @@ -403,17 +476,28 @@ void threads_thread_start(java_lang_Thread *object) #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 @@ -443,10 +527,14 @@ void threads_thread_print_info(threadobject *t) 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("\""); @@ -456,7 +544,7 @@ void threads_thread_print_info(threadobject *t) 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)",