You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2006/10/09 18:02:02 UTC
svn commit: r454411 [2/5] - in /incubator/harmony/enhanced/drlvm/trunk:
build/make/ build/make/targets/ vm/gcv4/src/ vm/include/ vm/include/open/
vm/interpreter/src/ vm/jitrino/src/vm/drl/ vm/port/src/encoder/ia32_em64t/
vm/port/src/lil/ vm/port/src/li...
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/tests/unit/thread/utils/thread_unit_test_vm_emulator.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/tests/unit/thread/utils/thread_unit_test_vm_emulator.c?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/tests/unit/thread/utils/thread_unit_test_vm_emulator.c (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/tests/unit/thread/utils/thread_unit_test_vm_emulator.c Mon Oct 9 09:01:52 2006
@@ -1,197 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "testframe.h"
-#include "thread_unit_test_utils.h"
-#include <assert.h>
-#include <apr-1/apr_pools.h>
-#include <open/hythread.h>
-#include <open/hythread_ext.h>
-#include <open/thread_externals.h>
-#include "thread_private.h"
-
-/*
- * VM emulator for thread manager unit tests
- */
-
-int vm_objects_are_equal(jobject obj1, jobject obj2);
-
-jmethodID isDaemonID = (jmethodID)&isDaemonID;
-jmethodID runID = (jmethodID)&runID;
-jmethodID setDaemonID = (jmethodID)&setDaemonID;
-struct JNINativeInterface_ jni_vtable;
-JNIEnv common_env = & jni_vtable;
-apr_pool_t *pool = NULL;
-
-jthread new_jobject(){
-
- apr_status_t status;
- _jobject *obj;
- _jjobject *object;
-
- if (!pool){
- status = apr_pool_create(&pool, NULL);
- if (status) return NULL;
- }
-
- obj = apr_palloc(pool, sizeof(_jobject));
- object = apr_palloc(pool, sizeof(_jjobject));
- assert(obj);
- obj->object = object;
- obj->object->data = NULL;
- obj->object->daemon = 0;
- obj->object->name = NULL;
- return obj;
-}
-
-void delete_jobject(jobject obj){
-
-}
-
-JNIEnv * new_JNIEnv(){
- return &common_env;
-}
-
-void delete_JNIEnv(JNIEnv *env){
-}
-
-jclass JNICALL FindClass(JNIEnv *env, const char *name){
- return new_jobject();
-}
-
-jmethodID JNICALL GetMethodID(JNIEnv *env, jclass clazz,
- const char *name, const char *sig){
- if (! strcmp(name, "isDaemon")){
- return isDaemonID;
- } else if (! strcmp(name, "setDaemon")){
- return setDaemonID;
- } else if (! strcmp(name, "runImpl")){
- return runID;
- } else if (! strcmp(name, "<init>")){
- return runID;
- }
- log_info("GetMethodID emulator: UNKNOWN METHOD");
- assert(0);
- return 0;
-}
-
-jboolean JNICALL CallBooleanMethodA(JNIEnv *env, jobject obj,
- jmethodID methodID, jvalue * args){
- if (methodID == isDaemonID){
- return obj->object->daemon;
- }
- log_info("CallBooleanMethodA emulator: UNKNOWN METHOD");
- assert(0);
- return 0;
-}
-
-//void JNICALL CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...){
-//
-// printf("CallVoidMethod...\n");
-//}
-//
-void JNICALL CallVoidMethodA(JNIEnv *env, jobject obj,
- jmethodID methodID, jvalue * args){
-
- if (methodID == setDaemonID){
- obj->object->daemon = args[0].z;
- } else if (methodID == runID){
- obj->object->run_method();
- } else {
- log_info("CallVoidMethodA emulator: UNKNOWN METHOD");
- assert(0);
- }
-}
-
-const char* JNICALL GetStringUTFChars(JNIEnv *env, jstring str, jboolean *isCopy){
- return str->object->name;
-}
-
-jstring JNICALL NewStringUTF(JNIEnv *env, const char * name){
-
- jstring jname = new_jobject();
- jname->object->name = (char *)name;
- return jname;
-}
-
-jobject JNICALL NewGlobalRef(JNIEnv *env, jobject object){
- jobject obj = new_jobject();
- assert(obj);
- assert(object);
- obj->object = object->object;
- return obj;
-}
-
-void JNICALL DeleteGlobalRef(JNIEnv *env, jobject object){
-}
-
-void JNICALL ReleaseStringUTFChars(JNIEnv *env, jstring str, const char* chars){
-}
-
-jint JNICALL ThrowNew (JNIEnv *env, jclass clazz, const char* chars){
- tested_thread_sturct_t * tts;
- hythread_t tm_native_thread;
- jvmti_thread_t tm_java_thread;
-
- tm_native_thread = hythread_self();
- tm_java_thread = hythread_get_private_data(tm_native_thread);
-
- reset_tested_thread_iterator(&tts);
- while(next_tested_thread(&tts)){
- if (vm_objects_are_equal(tts->java_thread, tm_java_thread->thread_object)){
- tts->excn = clazz;
- return 0;
- }
- }
- return 1;
-}
-
-jint JNICALL Throw (JNIEnv *env, jobject clazz){
- tested_thread_sturct_t * tts;
- hythread_t tm_native_thread;
- jvmti_thread_t tm_java_thread;
-
- tm_native_thread = hythread_self();
- tm_java_thread = hythread_get_private_data(tm_native_thread);
-
- reset_tested_thread_iterator(&tts);
- while(next_tested_thread(&tts)){
- if (vm_objects_are_equal(tts->java_thread, tm_java_thread->thread_object)){
- tts->excn = clazz;
- return 0;
- }
- }
- return 1;
-}
-
-
-void jni_init(){
-
- jni_vtable.FindClass = &FindClass;
- jni_vtable.GetMethodID = &GetMethodID;
- jni_vtable.CallBooleanMethodA = &CallBooleanMethodA;
- //jni_vtable.CallVoidMethod = &CallVoidMethod;
- jni_vtable.CallVoidMethodA = &CallVoidMethodA;
- jni_vtable.GetStringUTFChars = &GetStringUTFChars;
- jni_vtable.NewStringUTF = &NewStringUTF;
- jni_vtable.DeleteGlobalRef = &DeleteGlobalRef;
- jni_vtable.NewGlobalRef = &NewGlobalRef;
- jni_vtable.ReleaseStringUTFChars = &ReleaseStringUTFChars;
- jni_vtable.ThrowNew = ThrowNew;
- jni_vtable.Throw = Throw;
-}
-
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/tests/unit/thread/utils/tm2vm.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/tests/unit/thread/utils/tm2vm.c?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/tests/unit/thread/utils/tm2vm.c (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/tests/unit/thread/utils/tm2vm.c Mon Oct 9 09:01:52 2006
@@ -1,133 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @author Artem Aliev
- * @version $Revision$
- */
-
-#include "thread_private.h"
-#include <open/hythread_ext.h>
-#include "open/thread_externals.h"
-#include "thread_unit_test_utils.h"
-
-/**
- * This file contains the functions which eventually should become part of vmcore.
- * This localizes the dependencies of Thread Manager on vmcore component.
- */
-
-void *vm_object_get_lockword_addr(jobject monitor){
- //return (*(ManagedObject**)monitor)->get_obj_info_addr();
- return (void *)&monitor->object->lockword;
-}
-
-void* vm_jthread_get_tm_data(jthread thread)
-{
- /*
- JNIEnv *jenv = (JNIEnv*)jni_native_intf;
- jclass jThreadClass = jenv->GetObjectClass(thread);
- jfieldID field_id = jenv->GetFieldID(jThreadClass, "vm_thread", "J");
- POINTER_SIZE_INT data = (POINTER_SIZE_INT)jenv->GetLongField(thread, field_id);
-
- return (void *)data;
- */
- return thread->object->data;
-}
-
-void vm_jthread_set_tm_data(jthread jt, void* nt) {
- /*
- JNIEnv *jenv = (JNIEnv*)jni_native_intf;
- jclass jthreadclass = jenv->GetObjectClass(jt);
- jfieldID field_id = jenv->GetFieldID(jthreadclass, "vm_thread", "J");
- jenv->SetLongField(jt, field_id, (jlong)(POINTER_SIZE_INT)nt);
- */
- jt->object->data = nt;
-}
-
-IDATA jthread_throw_exception(char* name, char* message) {
- return 0;
-}
-VMEXPORT IDATA jthread_throw_exception_object(jobject object) {
- return 0;
-}
-
-int vm_objects_are_equal(jobject obj1, jobject obj2){
- //ObjectHandle h1 = (ObjectHandle)obj1;
- //ObjectHandle h2 = (ObjectHandle)obj2;
- if (obj1 == NULL && obj2 == NULL){
- return 1;
- }
- if (obj1 == NULL || obj2 == NULL){
- return 0;
- }
- return obj1->object == obj2->object;
-}
-
-void * vm_get_object(jobject obj){
- if (obj == NULL){
- return NULL;
- }
- return obj->object;
-}
-
-
-int ti_is_enabled(){
- return 1;
-}
-//--------------------------------------------------------------------------------
-
-IDATA vm_attach() {
- return 0;
-}
-IDATA vm_detach() {
- return 0;
-}
-void jvmti_send_thread_start_end_event(int is_start) {
- //is_start ? process_jvmti_event(JVMTI_EVENT_THREAD_START, 0, 0)
- // :process_jvmti_event(JVMTI_EVENT_THREAD_END, 1, 0);
-}
-void jvmti_send_wait_monitor_event(jobject monitor, jlong timeout) {
- hythread_t tm_native_thread = hythread_self();
- //TRACE2("jvmti.monitor.wait", "Monitor wait event, monitor = " << monitor);
- tm_native_thread->state &= ~TM_THREAD_STATE_RUNNABLE;
- tm_native_thread->state |= TM_THREAD_STATE_WAITING | TM_THREAD_STATE_IN_MONITOR_WAIT;
- tm_native_thread->state |= timeout ? TM_THREAD_STATE_WAITING_WITH_TIMEOUT :
- TM_THREAD_STATE_WAITING_INDEFINITELY;
- //process_jvmti_event(JVMTI_EVENT_MONITOR_WAIT, 1, monitor, timeout);
-}
-void jvmti_send_waited_monitor_event(jobject monitor, jboolean is_timed_out) {
- hythread_t tm_native_thread = hythread_self();
- //TRACE2("jvmti.monitor.waited", "Monitor wait event, monitor = " << monitor);
- tm_native_thread->state &= ~(TM_THREAD_STATE_WAITING | TM_THREAD_STATE_IN_MONITOR_WAIT |
- TM_THREAD_STATE_WAITING_INDEFINITELY |
- TM_THREAD_STATE_WAITING_WITH_TIMEOUT);
- tm_native_thread->state |= TM_THREAD_STATE_RUNNABLE;
- //process_jvmti_event(JVMTI_EVENT_MONITOR_WAITED, 1, monitor, is_timed_out);
-}
-void jvmti_send_contended_enter_or_entered_monitor_event(jobject monitor, int isEnter) {
- hythread_t tm_native_thread = hythread_self();
- //TRACE2("jvmti.monitor.enter", "Monitor enter event, monitor = " << monitor << " is enter= " << isEnter);
- if(isEnter){
- tm_native_thread->state |= TM_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
- tm_native_thread->state &= ~TM_THREAD_STATE_RUNNABLE;
- //process_jvmti_event(JVMTI_EVENT_MONITOR_CONTENDED_ENTER, 1, monitor);
- } else {
- tm_native_thread->state &= ~TM_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
- tm_native_thread->state |= TM_THREAD_STATE_RUNNABLE;
- //process_jvmti_event(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, 1, monitor);
- }
-}
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def Mon Oct 9 09:01:52 2006
@@ -9,6 +9,7 @@
hythread_monitor_enter
hythread_monitor_notify_all
hythread_attach
+hythread_attach_ex
hythread_monitor_destroy
hythread_monitor_num_waiting
hythread_interrupted
@@ -110,12 +111,14 @@
hymutex_destroy
-hythread_wait_for_all_nondaemon_threads
hythread_is_alive
hythread_is_terminated
hythread_init
-countdown_nondaemon_threads
-increase_nondaemon_threads_count
+hythread_shutdown
+hythread_lib_create
+hythread_lib_destroy
+hythread_lib_lock
+hythread_lib_unlock
release_start_lock
acquire_start_lock
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp Mon Oct 9 09:01:52 2006
@@ -8,6 +8,7 @@
hythread_monitor_enter;
hythread_monitor_notify_all;
hythread_attach;
+hythread_attach_ex;
hythread_monitor_destroy;
hythread_monitor_num_waiting;
hythread_interrupted;
@@ -121,11 +122,13 @@
hymutex_destroy;
hythread_exit;
-hythread_wait_for_all_nondaemon_threads;
hythread_is_alive;
hythread_init;
-countdown_nondaemon_threads;
-increase_nondaemon_threads_count;
+hythread_shutdown;
+hythread_lib_create;
+hythread_lib_destroy;
+hythread_lib_lock;
+hythread_lib_unlock;
set_safepoint_callback;
release_start_lock;
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_init.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_init.c?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_init.c (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_init.c Mon Oct 9 09:01:52 2006
@@ -33,10 +33,9 @@
//global constants:
-//library instance
-
-hythread_library_t hythread_lib;
+// Global pointer to the threading library
+hythread_library_t TM_LIBRARY = NULL;
//Thread manager memory pool
apr_pool_t *TM_POOL = NULL;
@@ -45,7 +44,6 @@
apr_threadkey_t *TM_THREAD_KEY;
//Thread manager global lock
-hymutex_t TM_LOCK = NULL;
hymutex_t TM_START_LOCK = NULL;
hymutex_t FAT_MONITOR_TABLE_LOCK = NULL;
#define GLOBAL_MONITOR_NAME "global_monitor"
@@ -60,9 +58,6 @@
IDATA groups_count;
-IDATA nondaemon_thread_count;
-hycond_t nondaemon_thread_cond;
-
static IDATA init_group_list();
static IDATA destroy_group_list();
@@ -70,18 +65,60 @@
#include <windows.h>
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpres) {
if (dwReason == DLL_PROCESS_ATTACH) {
- hythread_init (NULL);
+ hythread_lib_create(&TM_LIBRARY);
}
return TRUE;
}
#else
void hythread_library_init(void) {
- hythread_init(NULL);
-
+ hythread_lib_create(&TM_LIBRARY);
}
#endif
/**
+ * Creates and initializes a threading library.
+ *
+ * @param[out] lib pointer to the created thread library
+ * @return The thead library's initStatus will be set to 0 on success or
+ * a negative value on failure.
+ *
+ * @see hythread_attach, hythread_shutdown
+ */
+IDATA VMCALL hythread_lib_create(hythread_library_t * lib) {
+ apr_status_t apr_status;
+
+ // Current implementation doesn't support more than one library instance.
+ if (TM_LIBRARY) {
+ *lib = TM_LIBRARY;
+ return TM_ERROR_NONE;
+ }
+
+ apr_status = apr_initialize();
+ assert(apr_status == APR_SUCCESS);
+
+ apr_status = apr_pool_create(&TM_POOL, NULL);
+ if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status);
+
+ *lib = (hythread_library_t) apr_palloc(TM_POOL, sizeof(HyThreadLibrary));
+ if (*lib == NULL) return TM_ERROR_OUT_OF_MEMORY;
+
+ hythread_init(*lib);
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Shut down the threading library.
+ *
+ * @param lib the library
+ * @return none
+ *
+ * @see hythread_lib_create
+ */
+void VMCALL hythread_lib_destroy(hythread_library_t lib) {
+ apr_pool_destroy(TM_POOL);
+}
+
+/**
* Initialize a threading library.
*
* @note This must only be called once.
@@ -96,23 +133,33 @@
* @see hythread_attach, hythread_shutdown
*/
void VMCALL hythread_init(hythread_library_t lib){
- apr_status_t apr_status;
+ apr_status_t apr_status;
IDATA status;
hythread_monitor_t *mon;
- // check the someone already init the library
- if(TM_LOCK) {
- return;
- }
+
+ // Current implementation doesn't support more than one library instance.
+ if (TM_LIBRARY == NULL) {
+ TM_LIBRARY = lib;
+ }
+ assert(TM_LIBRARY == lib);
+
+ // Check if someone already initialized the library.
+ if (TM_START_LOCK != NULL) {
+ return;
+ }
apr_status = apr_initialize();
assert(apr_status == APR_SUCCESS);
- apr_status = apr_pool_create(&TM_POOL, NULL);
- assert(apr_status == APR_SUCCESS);
+ // TM_POOL will be NULL if hythread_lib_create was not used to create the library
+ if (TM_POOL == NULL) {
+ apr_status = apr_pool_create(&TM_POOL, NULL);
+ assert(apr_status == APR_SUCCESS);
+ }
apr_status = apr_threadkey_private_create(&TM_THREAD_KEY, NULL, TM_POOL);
assert(apr_status == APR_SUCCESS);
- status = hymutex_create(&TM_LOCK, TM_MUTEX_NESTED);
+ status = hymutex_create(&lib->TM_LOCK, TM_MUTEX_NESTED);
assert (status == TM_ERROR_NONE);
status = hymutex_create(&TM_START_LOCK, TM_MUTEX_NESTED);
assert (status == TM_ERROR_NONE);
@@ -128,8 +175,8 @@
//nondaemon thread barrier
////
- nondaemon_thread_count = 0;
- status = hycond_create(&nondaemon_thread_cond);
+ lib->nondaemon_thread_count = 0;
+ status = hycond_create(&lib->nondaemon_thread_cond);
assert (status == TM_ERROR_NONE);
lock_table = (hythread_monitor_t *)malloc(sizeof(hythread_monitor_t)*table_size);
@@ -152,96 +199,51 @@
*
* @see hythread_init
*/
-IDATA VMCALL hythread_shutdown(){
- IDATA status;
- apr_status_t apr_status;
- if (destroy_group_list() == TM_ERROR_NONE) {
- status=hymutex_destroy(TM_LOCK);
- if (status != TM_ERROR_NONE) return status;
- status=hymutex_destroy(TM_START_LOCK);
- if (status != TM_ERROR_NONE) return status;
- apr_status=apr_threadkey_private_delete(TM_THREAD_KEY);
- if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status);
- apr_pool_destroy(TM_POOL);
- return TM_ERROR_NONE;
- }
- return TM_ERROR_RUNNING_THREADS;
+void VMCALL hythread_shutdown() {
+ hythread_lib_destroy(hythread_self()->library);
}
+
/**
- * Acquires the lock over threading subsystem.
- *
- * The lock blocks new thread creation and thread exit operations.
+ * Acquires global lock of the library assocciated with the current thread.
+ *
+ * @param[in] self current thread
*/
-IDATA VMCALL hythread_global_lock() {
- return hymutex_lock(TM_LOCK);
+void VMCALL hythread_lib_lock(hythread_t self) {
+ IDATA status;
+
+ assert(self == hythread_self());
+ status = hymutex_lock(self->library->TM_LOCK);
+ assert(status == TM_ERROR_NONE);
}
/**
- * Releases the lock over threading subsystem.
- *
+ * Releases global lock of the library assocciated with the current thread.
+ *
+ * @param[in] self current thread
*/
-IDATA VMCALL hythread_global_unlock() {
- return hymutex_unlock(TM_LOCK);
-}
-
-
-IDATA increase_nondaemon_threads_count() {
+void VMCALL hythread_lib_unlock(hythread_t self) {
IDATA status;
-
- status = hymutex_lock(TM_LOCK);
- if (status != TM_ERROR_NONE) return status;
- nondaemon_thread_count++;
- status = hymutex_unlock(TM_LOCK);
- return status;
+ assert(self == hythread_self());
+ status = hymutex_unlock(self->library->TM_LOCK);
+ assert(status == TM_ERROR_NONE);
}
-IDATA countdown_nondaemon_threads() {
- IDATA status;
-
- status = hymutex_lock(TM_LOCK);
- if (status != TM_ERROR_NONE) return status;
-
- if(nondaemon_thread_count <= 0) {
- status = hymutex_unlock(TM_LOCK);
- if (status != TM_ERROR_NONE) return status;
- return TM_ERROR_ILLEGAL_STATE;
- }
- TRACE(("TM: nondaemons decreased, thread: %p count: %d", tm_self_tls, nondaemon_thread_count));
- nondaemon_thread_count--;
- if(nondaemon_thread_count == 0) {
- status = hycond_notify_all(nondaemon_thread_cond);
- TRACE(("TM: nondaemons all dead, thread: %p count: %d", tm_self_tls, nondaemon_thread_count));
- if (status != TM_ERROR_NONE){
- hymutex_unlock(TM_LOCK);
- return status;
- }
- }
-
- status = hymutex_unlock(TM_LOCK);
- return status;
-}
/**
- * waiting all nondaemon thread's
+ * Acquires the lock over threading subsystem.
*
+ * The lock blocks new thread creation and thread exit operations.
*/
-IDATA VMCALL hythread_wait_for_all_nondaemon_threads() {
- IDATA status;
-
- status = hymutex_lock(TM_LOCK);
- if (status != TM_ERROR_NONE) return status;
+IDATA VMCALL hythread_global_lock() {
+ return hymutex_lock(TM_LIBRARY->TM_LOCK);
+}
- while (nondaemon_thread_count) {
- status = hycond_wait(nondaemon_thread_cond, TM_LOCK);
- //check interruption and other problems
- TRACE(("TM wait for nondaemons notified, count: %d", nondaemon_thread_count));
- if(status != TM_ERROR_NONE) {
- hymutex_unlock(TM_LOCK);
- return status;
- }
- }
- status = hymutex_unlock(TM_LOCK);
- return status;
+/**
+ * Releases the lock over threading subsystem.
+ *
+ */
+IDATA VMCALL hythread_global_unlock() {
+ return hymutex_unlock(TM_LIBRARY->TM_LOCK);;
}
hythread_group_t get_java_thread_group(void){
@@ -297,7 +299,6 @@
return hymutex_unlock(TM_START_LOCK);
}
-
/*
// very simple Map implementation
// current scenario use only one global so it works well
@@ -350,8 +351,7 @@
* 0 on failure.
*
*/
-UDATA*
-VMCALL hythread_global (char* name) {
+UDATA* VMCALL hythread_global (char* name) {
//hythread_monitor_enter(*p_global_monitor);
int index = find_entry(name);
if(index == -1) {
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_attrs.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_attrs.c?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_attrs.c (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_attrs.c Mon Oct 9 09:01:52 2006
@@ -51,3 +51,15 @@
hythread_t tm_native_thread = jthread_get_native_thread(java_thread);
return hythread_set_priority(tm_native_thread, priority);
}
+
+/**
+ * Returns daemon status for the specified thread.
+ *
+ * @param[in] java_thread thread those attribute is read
+ */
+jboolean jthread_is_daemon(jthread thread) {
+ jvmti_thread_t jvmti_thread;
+
+ jvmti_thread = hythread_get_private_data(hythread_self());
+ return jvmti_thread->daemon;
+}
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_basic.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_basic.c?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_basic.c (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_basic.c Mon Oct 9 09:01:52 2006
@@ -27,6 +27,7 @@
#include <open/jthread.h>
#include <open/hythread_ext.h>
+#include "open/thread_externals.h"
#include "thread_private.h"
#include "jni.h"
@@ -35,18 +36,19 @@
void stop_callback(void);
jmethodID getRunMethod(JNIEnv *env);
+IDATA increase_nondaemon_threads_count(hythread_t self);
+IDATA countdown_nondaemon_threads(hythread_t self);
typedef struct {
- JNIEnv *jenv;
- jthread thread;
+ JavaVM * java_vm;
jboolean daemon;
- jvmtiEnv *tiEnv;
- jvmtiStartFunction tiProc;
- void *tiProcArgs;
+ jvmtiEnv *tiEnv;
+ jvmtiStartFunction tiProc;
+ void *tiProcArgs;
} wrapper_proc_data;
-IDATA associate_native_and_java_thread(JNIEnv* env, jthread java_thread, hythread_t tm_native_thread, jobject thread_ref);
+IDATA associate_native_and_java_thread(JNIEnv* env, jthread java_thread, hythread_t tm_native_thread, jobject thread_ref);
/**
* Creates new Java thread.
@@ -54,70 +56,60 @@
* The newly created thread will immediately start to execute the <code>run()</code>
* method of the appropriate <code>thread</code> object.
*
- * @param[in] env JNI environment that will be associated with the created Java thread
+ * @param[in] jni_env jni environment for the current thread.
* @param[in] java_thread Java thread object with which new thread must be associated.
* @param[in] attrs thread attributes.
* @sa java.lang.Thread.run()
*/
-IDATA jthread_create(JNIEnv* env, jthread java_thread, jthread_threadattr_t *attrs) {
+IDATA jthread_create(JNIEnv * jni_env, jthread java_thread, jthread_threadattr_t *attrs) {
- IDATA status;
- status = jthread_create_with_function(env,java_thread,attrs,NULL,NULL);
- return status;
+ return jthread_create_with_function(jni_env, java_thread, attrs, NULL, NULL);
}
int wrapper_proc(void *arg) {
-
- IDATA status,status1;
+ IDATA status;
+ JNIEnv * jni_env;
+ hythread_t native_thread;
+ jvmti_thread_t jvmti_thread;
+ jthread java_thread;
wrapper_proc_data *data = (wrapper_proc_data *)arg;
- JNIEnv *env = data->jenv;
- jvmtiEnv *tiEnv = data->tiEnv;
- jvmtiStartFunction tiProc = data->tiProc;
- void *tiProcArgs = data->tiProcArgs;
-
- TRACE(("TM: Java thread started: id=%d OS_handle=%p", hythread_self()->thread_id, apr_os_thread_current()));
- //status = hythread_global_lock();
- //assert (status == TM_ERROR_NONE);
- status=vm_attach();
- if(status!=TM_ERROR_NONE)
- {
- if (!data->daemon){
- status1 = countdown_nondaemon_threads();
- assert (status1 == TM_ERROR_NONE);
- }
- return status;
+
+ // Assocciation should be already done.
+ native_thread = hythread_self();
+ jvmti_thread = hythread_get_private_data(native_thread);
+ assert(jvmti_thread);
+ java_thread = jvmti_thread->thread_object;
+
+ status = vm_attach(data->java_vm, &jni_env);
+ if (status != JNI_OK) return TM_ERROR_INTERNAL;
+
+ jvmti_thread->jenv = jni_env;
+ jvmti_thread->daemon = data->daemon;
+
+ if (!jvmti_thread->daemon) {
+ increase_nondaemon_threads_count(native_thread);
}
+
+ TRACE(("TM: Java thread started: id=%d OS_handle=%p", native_thread->thread_id, apr_os_thread_current()));
+
+ // Send Thread Start event.
jvmti_send_thread_start_end_event(1);
- //status = hythread_global_unlock();
- // assert (status == TM_ERROR_NONE);
- if(tiProc!=NULL)
- {
- tiProc(tiEnv, env, tiProcArgs);
- }
- else
- {
- (*env) -> CallVoidMethodA(env, data->thread, getRunMethod(env), NULL);//for jthread_create();
- }
- jvmti_send_thread_start_end_event(0);
- (*env) -> DeleteGlobalRef(env, data->thread);
- TRACE(("TM: Java thread finished: id=%d OS_handle=%p", hythread_self()->thread_id, apr_os_thread_current()));
- assert(hythread_is_suspend_enabled());
- status=vm_detach();
- if(status!=TM_ERROR_NONE)
+ if(data->tiProc != NULL)
{
- if (!data->daemon){
- status1 = countdown_nondaemon_threads();
- assert (status1 == TM_ERROR_NONE);
- }
- return status;
+ data->tiProc(data->tiEnv, jni_env, data->tiProcArgs);
}
- assert(hythread_is_suspend_enabled());
- if (!data->daemon){
- status = countdown_nondaemon_threads();
- assert (status == TM_ERROR_NONE);
- }
- return TM_ERROR_NONE;
+ else
+ {
+ // for jthread_create();
+ (*jni_env) -> CallVoidMethodA(jni_env, java_thread, getRunMethod(jni_env), NULL);
+ }
+
+ status = jthread_detach(java_thread);
+
+ TRACE(("TM: Java thread finished: id=%d OS_handle=%p", native_thread->thread_id, apr_os_thread_current()));
+
+ return status;
}
/**
@@ -129,72 +121,57 @@
* This method of thread creation would be useful for creating TI agent threads (i.e. Java threads
* which always execute only native code).
*
- * @param[in] env JNI environment that will be associated with the created Java thread
+ * @param[in] jni_env jni environment for the current thread.
* @param[in] java_thread Java thread object with which new thread must be associated.
* @param[in] attrs thread attributes.
* @param[in] proc the start function to be executed in this thread.
* @param[in] arg The argument to the start function. Is passed as an array.
* @sa JVMTI::RunAgentThread()
*/
-IDATA jthread_create_with_function(JNIEnv *env, jthread java_thread, jthread_threadattr_t *attrs,jvmtiStartFunction proc, const void* arg)
+IDATA jthread_create_with_function(JNIEnv * jni_env, jthread java_thread, jthread_threadattr_t *attrs, jvmtiStartFunction proc, const void* arg)
{
- hythread_t tm_native_thread = NULL;
- jvmti_thread_t tm_java_thread = NULL;
- wrapper_proc_data *data;
- IDATA status;
- apr_status_t apr_status;
- apr_pool_t * pool;
-
- if (env == NULL || java_thread == NULL || attrs == NULL){
- return TM_ERROR_NULL_POINTER;
- }
+ hythread_t tm_native_thread = NULL;
+ jvmti_thread_t tm_java_thread;
+ wrapper_proc_data * data;
+ IDATA status;
+
+ if (jni_env == NULL || java_thread == NULL || attrs == NULL) {
+ return TM_ERROR_NULL_POINTER;
+ }
tm_native_thread = vm_jthread_get_tm_data(java_thread);
-
- //This is for irregular use. In ordinary live valid jthread instance
- //contains weak reference associated with it and native thread to reuse
- //if any
- ////
-
- if (tm_native_thread==NULL)
- {
- if(!jthread_thread_init(NULL,env,java_thread, NULL, 0))
- {
- return TM_ERROR_OUT_OF_MEMORY;
- }
- tm_native_thread = vm_jthread_get_tm_data(java_thread);
+
+ // This is for irregular use. In ordinary live valid jthread instance
+ // contains weak reference associated with it and native thread to reuse.
+ if (tm_native_thread == NULL) {
+ if( !jthread_thread_init(NULL, jni_env, java_thread, NULL, 0)) {
+ return TM_ERROR_OUT_OF_MEMORY;
}
+ tm_native_thread = vm_jthread_get_tm_data(java_thread);
+ }
+
tm_java_thread = hythread_get_private_data(tm_native_thread);
- assert(tm_java_thread);
- apr_status = apr_pool_create(&pool, 0);
- if (apr_status != APR_SUCCESS) {
- return CONVERT_ERROR(apr_status);
- }
- data = apr_palloc(pool, sizeof(wrapper_proc_data));
- if(data == NULL) {
- return TM_ERROR_OUT_OF_MEMORY;
- }
+ assert(tm_java_thread);
+ data = apr_palloc(tm_java_thread->pool, sizeof(wrapper_proc_data));
+ if (data == NULL) {
+ return TM_ERROR_OUT_OF_MEMORY;
+ }
+
// Prepare argumets for wrapper proc
- data->jenv = env;
- data->thread = tm_java_thread->thread_object;
+ status = (*jni_env) -> GetJavaVM(jni_env, &data->java_vm);
+ if (status != JNI_OK) return TM_ERROR_INTERNAL;
+
data->daemon = attrs->daemon;
- data->tiEnv = attrs->jvmti_env;
+ data->tiEnv = attrs->jvmti_env;
data->tiProc = proc;
data->tiProcArgs = (void *)arg;
- // create native thread with wrapper_proc
- if (!attrs->daemon){
- status = increase_nondaemon_threads_count();
- if (status != TM_ERROR_NONE) return status;
- }
- status = hythread_create(&tm_native_thread, (attrs->stacksize)?attrs->stacksize:1024000,
- attrs->priority, 0, wrapper_proc, data);
- if ((!attrs->daemon)&&(status != TM_ERROR_NONE)){
- countdown_nondaemon_threads();
- }
+ status = hythread_create(&tm_native_thread, (attrs->stacksize)?attrs->stacksize:1024000,
+ attrs->priority, 0, wrapper_proc, data);
+
TRACE(("TM: Created thread: id=%d", tm_native_thread->thread_id));
- return status;
+ return status;
}
/**
@@ -204,30 +181,39 @@
* and associate it with the current native thread. Nothing happens
* if this thread is already attached.
*
- * @param[in] env JNI environment that will be associated with the attached Java thread
- * @param[in] java_thread Java thread object with which the current native thread must be associated.
+ * @param[in] jni_env JNI environment for cuurent thread
+ * @param[in] java_thread j.l.Thread instance to associate with current thread
+ * @param[in] daemon JNI_TRUE if attaching thread is a daemon thread, JNI_FALSE overwise
* @sa JNI::AttachCurrentThread ()
*/
-IDATA jthread_attach(JNIEnv* env, jthread java_thread) {
-
+IDATA jthread_attach(JNIEnv * jni_env, jthread java_thread, jboolean daemon) {
hythread_t tm_native_thread;
+ jvmti_thread_t jvmti_thread;
IDATA status;
- status = hythread_attach(NULL);
- if (status != TM_ERROR_NONE){
- return status;
- }
- tm_native_thread = hythread_self();
- //I wonder if we need it.
- //since jthread already created, thus association is already done,
- //see jthread_init
- //VVVVVVVVVVVVVVVVVVVVVV
- status=associate_native_and_java_thread(env, java_thread, tm_native_thread, NULL);
- if (status != TM_ERROR_NONE){
- return status;
+
+ // Do nothing if thread already attached.
+ if (jthread_self() != NULL) return TM_ERROR_NONE;
+
+ tm_native_thread = hythread_self();
+ assert(tm_native_thread);
+
+ status = associate_native_and_java_thread(jni_env, java_thread, tm_native_thread, NULL);
+ if (status != TM_ERROR_NONE) return status;
+
+ jvmti_thread = hythread_get_private_data(tm_native_thread);
+ assert(jvmti_thread);
+ jvmti_thread->jenv = jni_env;
+ jvmti_thread->daemon = daemon;
+
+ if (!jvmti_thread->daemon) {
+ increase_nondaemon_threads_count(tm_native_thread);
}
+
+ // Send Thread Start event.
+ jvmti_send_thread_start_end_event(1);
+
TRACE(("TM: Current thread attached to jthread=%p", java_thread));
- status=vm_attach();
- return status;
+ return TM_ERROR_NONE;
}
/**
@@ -243,25 +229,24 @@
jlong jthread_thread_init(jvmti_thread_t *ret_thread, JNIEnv* env, jthread java_thread, jobject weak_ref, jlong old_thread) {
hythread_t tm_native_thread = NULL;
jvmti_thread_t tmj_thread;
- IDATA status;
+ IDATA status;
if (old_thread) {
tm_native_thread = (hythread_t)((IDATA)old_thread);
tmj_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread);
//delete used weak reference
- if (tmj_thread->thread_ref) (*env)->DeleteGlobalRef(env, tmj_thread->thread_ref);
-
+ if (tmj_thread->thread_ref) (*env)->DeleteGlobalRef(env, tmj_thread->thread_ref);
+ }
+
+ status = hythread_struct_init(&tm_native_thread);
+ if (status != TM_ERROR_NONE) {
+ return 0;
+ }
+
+ status = associate_native_and_java_thread(env, java_thread, tm_native_thread, weak_ref);
+ if (status != TM_ERROR_NONE) {
+ return 0;
}
- status = hythread_struct_init(&tm_native_thread, NULL);
- if(status != TM_ERROR_NONE)
- {
- return 0;
- }
- status=associate_native_and_java_thread(env, java_thread, tm_native_thread, weak_ref);
- if(status != TM_ERROR_NONE)
- {
- return 0;
- }
return (jlong)((IDATA)tm_native_thread);
}
@@ -273,66 +258,73 @@
* @param[in] java_thread Java thread to be detached
*/
IDATA jthread_detach(jthread java_thread) {
- jvmti_thread_t tm_java_thread;
+ IDATA status;
hythread_t tm_native_thread;
+ jvmti_thread_t tm_jvmti_thread;
+ JNIEnv * jni_env;
+
+ assert(hythread_is_suspend_enabled());
- // Check input arg
+ // Check input arg
assert(java_thread);
- TRACE(("TM: jthread_detach %x", hythread_self()));
+ TRACE(("TM: jthread_detach %x", hythread_self()));
- tm_native_thread = vm_jthread_get_tm_data(java_thread);
- tm_java_thread = hythread_get_private_data(tm_native_thread);
+ tm_native_thread = jthread_get_native_thread(java_thread);
+ tm_jvmti_thread = hythread_get_private_data(tm_native_thread);
+ jni_env = tm_jvmti_thread->jenv;
- // Remove tm_thread_t pointer from java.lang.Thread object
- vm_jthread_set_tm_data(java_thread, NULL);
-
- vm_detach();
-
- // Deallocate tm_java_thread
- apr_pool_destroy(tm_java_thread->pool);
-
- // Remove tm_jthread_t pointer from *tm_native_thread
- /*
- status = hythread_set_private_data(tm_native_thread, NULL);
- if (status != TM_ERROR_NONE){
- return status;
- }*/
- assert(hythread_is_suspend_enabled());
+ if (!tm_jvmti_thread->daemon){
+ countdown_nondaemon_threads(tm_native_thread);
+ }
+
+ // Send Thread End event
+ jvmti_send_thread_start_end_event(0);
+
+ // Detach from VM.
+ status = vm_detach(java_thread);
+ if (status != JNI_OK) return TM_ERROR_INTERNAL;
+
+ // Delete global reference to current thread object.
+ (*jni_env)->DeleteGlobalRef(jni_env, tm_jvmti_thread->thread_object);
+ // jthread_self() will return NULL now.
+ tm_jvmti_thread->thread_object = NULL;
+
+
+ // Deallocate tm_jvmti_thread
+ //apr_pool_destroy(tm_jvmti_thread->pool);
+
+ assert(hythread_is_suspend_enabled());
return TM_ERROR_NONE;
}
-IDATA associate_native_and_java_thread(JNIEnv* env, jthread java_thread, hythread_t tm_native_thread, jobject thread_ref)
+IDATA associate_native_and_java_thread(JNIEnv * jni_env, jthread java_thread, hythread_t tm_native_thread, jobject thread_ref)
{
- IDATA status;
+ IDATA status;
apr_status_t apr_status;
apr_pool_t *pool;
- jvmti_thread_t tm_java_thread;
- if ((env == NULL) || (java_thread == NULL)||(tm_native_thread==NULL)){
+ jvmti_thread_t tm_java_thread;
+
+ if ((jni_env == NULL) || (java_thread == NULL) || (tm_native_thread == NULL)) {
return TM_ERROR_NULL_POINTER;
}
-
tm_java_thread = hythread_get_private_data(tm_native_thread);
if (!tm_java_thread) {
apr_status = apr_pool_create(&pool, 0);
- if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status);
- if (pool==NULL) return TM_ERROR_OUT_OF_MEMORY;
+ if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status);
+ if (pool == NULL) return TM_ERROR_OUT_OF_MEMORY;
tm_java_thread = apr_palloc(pool, sizeof(JVMTIThread));
- if(tm_java_thread == NULL) {
- return TM_ERROR_OUT_OF_MEMORY;
- }
+ if (tm_java_thread == NULL) return TM_ERROR_OUT_OF_MEMORY;
tm_java_thread->pool = pool;
status = hythread_set_private_data(tm_native_thread, tm_java_thread);
- if (status != TM_ERROR_NONE){
- return status;
- }
+ if (status != TM_ERROR_NONE) return status;
}
-
- tm_java_thread->jenv = env;
- tm_java_thread->thread_object = (*env)->NewGlobalRef(env,java_thread);
- tm_java_thread->thread_ref = (thread_ref)?(*env)->NewGlobalRef(env, thread_ref):NULL;
+ // JNI environment is created when this thread attaches to VM.
+ tm_java_thread->jenv = NULL;
+ tm_java_thread->thread_object = (*jni_env)->NewGlobalRef(jni_env, java_thread);
+ tm_java_thread->thread_ref = (thread_ref) ? (*jni_env)->NewGlobalRef(jni_env, thread_ref) : NULL;
tm_java_thread->contended_monitor = 0;
tm_java_thread->wait_monitor = 0;
tm_java_thread->owned_monitors = 0;
@@ -343,7 +335,7 @@
// Associate java_thread with tm_thread
vm_jthread_set_tm_data(java_thread, tm_native_thread);
- return TM_ERROR_NONE;
+ return TM_ERROR_NONE;
}
/**
@@ -355,18 +347,17 @@
* @sa java.lang.Thread.join()
*/
IDATA jthread_join(jthread java_thread) {
-
+ IDATA status;
hythread_t tm_native_thread;
- IDATA status;
-
- if (java_thread == NULL){
- return TM_ERROR_NULL_POINTER;
- }
+
+ if (java_thread == NULL) {
+ return TM_ERROR_NULL_POINTER;
+ }
tm_native_thread = jthread_get_native_thread(java_thread);
status = hythread_join_interruptable(tm_native_thread, 0, 0);
TRACE(("TM: jthread %d joined %d", hythread_self()->thread_id, tm_native_thread->thread_id));
-
- return status;
+
+ return status;
}
/**
@@ -488,17 +479,20 @@
IDATA status;
tm_native_thread->state &= ~TM_THREAD_STATE_RUNNABLE;
- tm_native_thread->state |= TM_THREAD_STATE_WAITING | TM_THREAD_STATE_SLEEPING |
- TM_THREAD_STATE_WAITING_WITH_TIMEOUT;
+ tm_native_thread->state |= TM_THREAD_STATE_WAITING | TM_THREAD_STATE_SLEEPING |
+ TM_THREAD_STATE_WAITING_WITH_TIMEOUT;
status = hythread_sleep_interruptable(millis, nanos);
+#ifndef NDEBUG
+ if (status == TM_ERROR_INTERRUPT) {
+ TRACE(("TM: sleep interrupted status received, thread: %p", hythread_self()));
+ }
+#endif
+
+ tm_native_thread->state &= ~(TM_THREAD_STATE_WAITING | TM_THREAD_STATE_SLEEPING |
+ TM_THREAD_STATE_WAITING_WITH_TIMEOUT);
- tm_native_thread->state &= ~(TM_THREAD_STATE_WAITING | TM_THREAD_STATE_SLEEPING |
- TM_THREAD_STATE_WAITING_WITH_TIMEOUT);
tm_native_thread->state |= TM_THREAD_STATE_RUNNABLE;
- if (status == TM_ERROR_INTERRUPT) {
- TRACE(("TM: sleep interrupted status received, thread: %p", hythread_self()));
- }
return status;
}
@@ -511,21 +505,20 @@
* @param[in] java_thread java.lang.Thread object
*/
JNIEnv *jthread_get_JNI_env(jthread java_thread) {
+ hythread_t tm_native_thread;
+ jvmti_thread_t tm_java_thread;
- hythread_t tm_native_thread;
- jvmti_thread_t tm_java_thread;
-
- if (java_thread == NULL){
+ if (java_thread == NULL) {
return NULL;
- }
- tm_native_thread = jthread_get_native_thread(java_thread);
- if (tm_native_thread == NULL){
+ }
+ tm_native_thread = jthread_get_native_thread(java_thread);
+ if (tm_native_thread == NULL) {
return NULL;
- }
- tm_java_thread = hythread_get_private_data(tm_native_thread);
- if (tm_java_thread == NULL){
+ }
+ tm_java_thread = hythread_get_private_data(tm_native_thread);
+ if (tm_java_thread == NULL) {
return NULL;
- }
+ }
return tm_java_thread->jenv;
}
/**
@@ -540,11 +533,11 @@
jlong jthread_get_id(jthread java_thread) {
hythread_t tm_native_thread;
-
- tm_native_thread = jthread_get_native_thread(java_thread);
+
+ tm_native_thread = jthread_get_native_thread(java_thread);
assert(tm_native_thread);
-
- return hythread_get_id(tm_native_thread);
+
+ return hythread_get_id(tm_native_thread);
}
/**
@@ -554,19 +547,19 @@
* @return jthread for the given ID, or NULL if there are no such.
*/
jthread jthread_get_thread(jlong thread_id) {
-
- hythread_t tm_native_thread;
- jvmti_thread_t tm_java_thread;
- jthread java_thread;
+
+ hythread_t tm_native_thread;
+ jvmti_thread_t tm_java_thread;
+ jthread java_thread;
tm_native_thread = hythread_get_thread((jint)thread_id);
- if (tm_native_thread == NULL){
+ if (tm_native_thread == NULL) {
return NULL;
- }
- tm_java_thread = hythread_get_private_data(tm_native_thread);
- java_thread = tm_java_thread->thread_object;
+ }
+ tm_java_thread = hythread_get_private_data(tm_native_thread);
+ java_thread = tm_java_thread->thread_object;
assert(java_thread);
- return java_thread;
+ return java_thread;
}
/**
@@ -575,9 +568,8 @@
* @return native thread
*/
hythread_t jthread_get_native_thread(jthread thread) {
-
- assert(thread);
-
+
+ assert(thread);
return vm_jthread_get_tm_data(thread);
}
@@ -587,19 +579,19 @@
* @return Java thread
*/
jthread jthread_get_java_thread(hythread_t tm_native_thread) {
+
+ jvmti_thread_t tm_java_thread;
- jvmti_thread_t tm_java_thread;
-
- if (tm_native_thread == NULL){
+ if (tm_native_thread == NULL) {
TRACE(("TM: native thread is NULL"));
return NULL;
- }
- tm_java_thread = hythread_get_private_data(tm_native_thread);
+ }
+ tm_java_thread = hythread_get_private_data(tm_native_thread);
- if (tm_java_thread == NULL){
+ if (tm_java_thread == NULL) {
TRACE(("TM: tmj thread is NULL"));
return NULL;
- }
+ }
return tm_java_thread->thread_object;
}
@@ -610,7 +602,6 @@
* or NULL if the current native thread is not attached to JVM.
*/
jthread jthread_self(void) {
-
return jthread_get_java_thread(hythread_self());
}
@@ -622,6 +613,42 @@
return hythread_cancel_all(NULL);
}
+/**
+ * waiting all nondaemon thread's
+ *
+ */
+IDATA VMCALL jthread_wait_for_all_nondaemon_threads() {
+ hythread_t native_thread;
+ jvmti_thread_t jvmti_thread;
+ hythread_library_t lib;
+ IDATA status;
+
+ native_thread = hythread_self();
+ jvmti_thread = hythread_get_private_data(native_thread);
+ lib = native_thread->library;
+
+ status = hymutex_lock(lib->TM_LOCK);
+ if (status != TM_ERROR_NONE) return status;
+
+ if (lib->nondaemon_thread_count == 1 && !jvmti_thread->daemon) {
+ status = hymutex_unlock(lib->TM_LOCK);
+ return status;
+ }
+
+ while (lib->nondaemon_thread_count) {
+ status = hycond_wait(lib->nondaemon_thread_cond, lib->TM_LOCK);
+ //check interruption and other problems
+ TRACE(("TM wait for nondaemons notified, count: %d", nondaemon_thread_count));
+ if(status != TM_ERROR_NONE) {
+ hymutex_unlock(lib->TM_LOCK);
+ return status;
+ }
+ }
+
+ status = hymutex_unlock(lib->TM_LOCK);
+ return status;
+}
+
/*
* Auxiliary function to throw java.lang.InterruptedException
*/
@@ -631,29 +658,74 @@
jvmti_thread_t tm_java_thread;
hythread_t tm_native_thread;
jclass clazz;
- JNIEnv *env;
- TRACE(("interrupted_exception thrown"));
+ JNIEnv *env;
+
+ TRACE(("interrupted_exception thrown"));
tm_native_thread = hythread_self();
tm_java_thread = hythread_get_private_data(tm_native_thread);
- env = tm_java_thread->jenv;
- clazz = (*env) -> FindClass(env, "java/lang/InterruptedException");
- (*env) -> ThrowNew(env, clazz, "Park() is interrupted");
+ env = tm_java_thread->jenv;
+ clazz = (*env) -> FindClass(env, "java/lang/InterruptedException");
+ (*env) -> ThrowNew(env, clazz, "Park() is interrupted");
}
jmethodID getRunMethod(JNIEnv *env) {
jclass clazz;
static jmethodID run_method = NULL;
- IDATA status;
+ IDATA status;
status=acquire_start_lock();
- assert (status == TM_ERROR_NONE);
+ assert (status == TM_ERROR_NONE);
//printf("run method find enter\n");
if (!run_method) {
clazz = (*env) -> FindClass(env, "java/lang/Thread");
- run_method = (*env) -> GetMethodID(env, clazz, "runImpl", "()V");
+ run_method = (*env) -> GetMethodID(env, clazz, "run", "()V");
}
status=release_start_lock();
//printf("run method find exit\n");
assert (status == TM_ERROR_NONE);
return run_method;
+}
+
+IDATA increase_nondaemon_threads_count(hythread_t self) {
+ hythread_library_t lib;
+ IDATA status;
+
+ lib = self->library;
+
+ status = hymutex_lock(lib->TM_LOCK);
+ if (status != TM_ERROR_NONE) return status;
+
+ lib->nondaemon_thread_count++;
+ status = hymutex_unlock(lib->TM_LOCK);
+ return status;
+}
+
+IDATA countdown_nondaemon_threads(hythread_t self) {
+ hythread_library_t lib;
+ IDATA status;
+
+ lib = self->library;
+
+ status = hymutex_lock(lib->TM_LOCK);
+ if (status != TM_ERROR_NONE) return status;
+
+ if(lib->nondaemon_thread_count <= 0) {
+ status = hymutex_unlock(lib->TM_LOCK);
+ if (status != TM_ERROR_NONE) return status;
+ return TM_ERROR_ILLEGAL_STATE;
+ }
+
+ TRACE(("TM: nondaemons decreased, thread: %p count: %d", self, lib->nondaemon_thread_count));
+ lib->nondaemon_thread_count--;
+ if(lib->nondaemon_thread_count == 0) {
+ status = hycond_notify_all(lib->nondaemon_thread_cond);
+ TRACE(("TM: nondaemons all dead, thread: %p count: %d", self, lib->nondaemon_thread_count));
+ if (status != TM_ERROR_NONE){
+ hymutex_unlock(lib->TM_LOCK);
+ return status;
+ }
+ }
+
+ status = hymutex_unlock(lib->TM_LOCK);
+ return status;
}
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_attrs.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_attrs.c?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_attrs.c (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_attrs.c Mon Oct 9 09:01:52 2006
@@ -46,7 +46,7 @@
*/
IDATA VMCALL hythread_set_priority(hythread_t thread, UDATA priority){
apr_status_t apr_status = apr_thread_set_priority(thread->os_handle, priority);
- if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status);
+ if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status);
thread->priority = priority;
return TM_ERROR_NONE;
}
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c Mon Oct 9 09:01:52 2006
@@ -31,10 +31,19 @@
#include <open/hythread_ext.h>
#include "thread_private.h"
+typedef struct {
+ hythread_t thread;
+ hythread_group_t group;
+ hythread_entrypoint_t start_proc;
+ void * start_proc_args;
+} thread_start_proc_data;
+
extern hythread_group_t TM_DEFAULT_GROUP;
+extern hythread_library_t TM_LIBRARY;
static void* APR_THREAD_FUNC thread_start_proc(apr_thread_t* thd, void *p_args);
-static hythread_t init_thread(hythread_group_t group);
+static hythread_t allocate_thread();
static void reset_thread(hythread_t thread);
+static IDATA register_to_group(hythread_t thread, hythread_group_t group);
//#define APR_TLS_USE 1
#define NAKED __declspec( naked )
@@ -51,6 +60,7 @@
#define MAX_ID 1000000
hythread_t fast_thread_array[MAX_ID];
int next_id = 1;
+
/*
IDATA add_to_fast_thread_array(hythread_t thread,int id)
{
@@ -87,18 +97,21 @@
IDATA VMCALL hythread_create_with_group(hythread_t *ret_thread, hythread_group_t group, UDATA stacksize, UDATA priority, UDATA suspend, hythread_entrypoint_t func, void *data) {
apr_threadattr_t *apr_attrs;
hythread_t new_thread;
+ thread_start_proc_data * start_proc_data;
apr_status_t apr_status;
- if (!ret_thread || !(*ret_thread)) {
- // Allocate & init thread structure
- new_thread = init_thread(group);
- if(new_thread==NULL){
- return TM_ERROR_OUT_OF_MEMORY;
- }
+ if (ret_thread) {
+ hythread_struct_init(ret_thread);
+ new_thread = *ret_thread;
} else {
- new_thread = (*ret_thread);
+ new_thread = allocate_thread();
+ }
+
+ if (new_thread == NULL) {
+ return TM_ERROR_OUT_OF_MEMORY;
}
+ new_thread->library = hythread_self()->library;
if (stacksize) {
apr_threadattr_create(&apr_attrs, new_thread->pool);
apr_threadattr_stacksize_set(apr_attrs, stacksize);
@@ -108,23 +121,27 @@
}
new_thread->priority = priority ? priority : HYTHREAD_PRIORITY_NORMAL;
+ new_thread->state = TM_THREAD_STATE_ALIVE;
//new_thread->suspend_request = suspend ? 1 : 0;
+ start_proc_data = (thread_start_proc_data *) apr_palloc(new_thread->pool, sizeof(thread_start_proc_data));
+ if (start_proc_data == NULL) {
+ return TM_ERROR_OUT_OF_MEMORY;
+ }
+
// Set up thread body procedure
- new_thread->start_proc = func;
- new_thread->start_proc_args = data;
- new_thread->state = TM_THREAD_STATE_ALIVE;
+ start_proc_data->thread = new_thread;
+ start_proc_data->group = group == NULL ? TM_DEFAULT_GROUP : group;
+ start_proc_data->start_proc = func;
+ start_proc_data->start_proc_args = data;
+
// Create APR thread using the given attributes;
- apr_status = apr_thread_create(&(new_thread->os_handle), // new thread OS handle
- new_thread->apr_attrs, // thread attr created here
- thread_start_proc, //
- (void *)new_thread, //thread_proc attrs
+ apr_status = apr_thread_create(&(new_thread->os_handle), // new thread OS handle
+ new_thread->apr_attrs, // thread attr created here
+ thread_start_proc, //
+ (void *)start_proc_data, //thread_proc attrs
new_thread->pool);
- // Store the pointer to the resulting thread
- if(ret_thread) {
- *ret_thread = new_thread;
- }
return CONVERT_ERROR(apr_status);
}
@@ -157,13 +174,18 @@
* Registers the current OS thread with the threading subsystem.
*
* @param[in] handle thread to register
+ * @param[in] lib thread library to attach to
* @param[in] group thread group, or NULL; in case of NULL this thread will go to the default group
*/
-IDATA VMCALL hythread_attach_to_group(hythread_t *handle, hythread_group_t group) {
+IDATA hythread_attach_to_group(hythread_t * handle, hythread_library_t lib, hythread_group_t group) {
hythread_t thread;
apr_thread_t *os_handle = NULL;
apr_os_thread_t *os_thread;
- apr_status_t apr_status;
+ apr_status_t apr_status;
+
+ if (lib == NULL) {
+ lib = TM_LIBRARY;
+ }
// Do nothing and return if the thread is already attached
thread = tm_self_tls;
@@ -173,30 +195,29 @@
}
return TM_ERROR_NONE;
}
- thread = init_thread(group); // allocate & init thread structure
- if (thread==NULL){
- return TM_ERROR_OUT_OF_MEMORY;
- }
+ if (handle) {
+ hythread_struct_init(handle);
+ thread = *handle;
+ } else {
+ thread = allocate_thread();
+ }
+ if (thread == NULL) {
+ return TM_ERROR_OUT_OF_MEMORY;
+ }
+ thread->library = lib;
os_thread = apr_palloc(thread->pool, sizeof(apr_os_thread_t));
- if(os_thread == NULL) {
+ if (os_thread == NULL) {
return TM_ERROR_OUT_OF_MEMORY;
- }
+ }
*os_thread = apr_os_thread_current();
apr_status = apr_os_thread_put(&os_handle, os_thread, thread->pool);
- if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status);
+ if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status);
thread->os_handle = os_handle;
- thread_set_self(thread);
-
- thread->state = TM_THREAD_STATE_ALIVE | TM_THREAD_STATE_RUNNABLE;
- assert(thread == tm_self_tls);
- TRACE(("TM: native attached: native: %p ", tm_self_tls));
- if (handle) {
- *handle = thread;
- }
+ TRACE(("TM: native attached: native: %p ", tm_self_tls));
- return TM_ERROR_NONE;
+ return register_to_group(thread, group == NULL ? TM_DEFAULT_GROUP : group);
}
/**
@@ -213,10 +234,25 @@
* @param[out] handle pointer to a hythread_t to be set (will be ignored if null)
* @return 0 on success or negative value on failure
*
+ * @note (*handle) should be NULL or point to hythread_t structure
* @see hythread_detach
*/
IDATA VMCALL hythread_attach(hythread_t *handle) {
- return hythread_attach_to_group(handle, NULL);
+ return hythread_attach_to_group(handle, TM_LIBRARY, NULL);
+}
+
+/**
+ * Attach an OS thread to the threading library.
+ *
+ * @param[out] handle pointer to a hythread_t to be set (will be ignored if null)
+ * @param[in] lib thread library to attach thread to
+ * @return 0 on success or negative value on failure
+ *
+ * @note (*handle) should be NULL or point to hythread_t structure
+ * @see hythread_detach
+ */
+IDATA VMCALL hythread_attach_ex(hythread_t *handle, hythread_library_t lib) {
+ return hythread_attach_to_group(handle, lib, NULL);
}
/**
@@ -237,22 +273,23 @@
*/
void VMCALL hythread_detach(hythread_t thread) {
// Acquire global TM lock to prevent concurrent acccess to thread list
- IDATA status;
- status = hythread_global_lock(NULL);
- assert (status == TM_ERROR_NONE);
-
- if (!(thread = tm_self_tls)) {
- status = hythread_global_unlock(NULL);
- assert (status == TM_ERROR_NONE);
- return;
- }
+ IDATA status;
- status = thread_destroy(thread); // Remove thread from the list of thread
+ assert(thread == tm_self_tls);
+ status = hythread_global_lock(NULL);
assert (status == TM_ERROR_NONE);
- thread_set_self(NULL);
- status = hythread_global_unlock(NULL);
- assert (status == TM_ERROR_NONE);
+
+ thread_set_self(NULL);
+ fast_thread_array[thread->thread_id] = NULL;
+
+ thread->prev->next = thread->next;
+ thread->next->prev = thread->prev;
+ thread->group->threads_count--;
+
+ hythread_global_unlock(NULL);
+ assert(status == TM_ERROR_NONE);
}
+
/**
* Waits until the selected thread finishes execution.
*
@@ -481,66 +518,6 @@
return TM_ERROR_NONE;
}
-//==============================================================================
-// Private functions
-/*
- */
-IDATA thread_destroy(hythread_t thread) {
-
- // Acquire global TM lock to prevent concurrent acccess to thread list
- IDATA status;
- status =hythread_global_lock(NULL);
- if (status != TM_ERROR_NONE) return status;
- thread->prev->next = thread->next;
- thread->next->prev = thread->prev;
- thread->group->threads_count--;
-
- //fast_thread_array[thread->thread_id] = NULL;
-
- status =hythread_global_unlock(NULL);
- if (status != TM_ERROR_NONE) return status;
- return TM_ERROR_NONE;
-}
-/*
- */
-IDATA allocate_thread(hythread_t thread, hythread_group_t group) {
- int id = 0;
- hythread_t cur, prev;
- IDATA status;
- //thread_list points to the dummy thread, which is not actual thread, just
- //a auxiliary thread structure to maintain the thread list
- /////
-
- // Acquire global TM lock to prevent concurrent acccess to thread list
- status =hythread_global_lock(NULL);
- if (status != TM_ERROR_NONE) return status;
-
- // Append the thread to the list of threads
- cur = group->thread_list->next;
- if (thread->thread_id) {
- id = thread->thread_id;
- } else {
- id = ++next_id;
- }
- if (id>=MAX_ID){
- hythread_global_unlock(NULL);
- return TM_ERROR_OUT_OF_MEMORY;
- }
- prev = cur->prev;
-
- thread->next = cur;
- thread->prev = prev;
- prev->next = cur->prev = thread;
- thread->thread_id = id;
- fast_thread_array[id] = thread;
- /*status=add_to_fast_thread_array(thread,id);
- if (status != TM_ERROR_NONE) return status;*/
- status=hythread_global_unlock(NULL);
- if (status != TM_ERROR_NONE) return status;
- return TM_ERROR_NONE;
-
-}
-
/**
* Terminates a running thread.
*
@@ -570,14 +547,14 @@
group = TM_DEFAULT_GROUP;
}
- iter = hythread_iterator_create (group);
+ iter = hythread_iterator_create(group);
while((next = hythread_iterator_next (&iter)) != NULL) {
- if(next != self) {
- hythread_cancel(next);
+ if(next != self) {
+ hythread_cancel(next);
//since this method being used at shutdown it does not
//males any sence to exit on error, but continue terminating threads
- }
- }
+ }
+ }
return TM_ERROR_NONE;
}
@@ -586,17 +563,54 @@
* Allocates and initializes a new thread_t structure.
*
*/
-IDATA VMCALL hythread_struct_init(hythread_t *ret_thread, hythread_group_t group) {
+IDATA VMCALL hythread_struct_init(hythread_t *ret_thread) {
if (*ret_thread) {
reset_thread(*ret_thread);
- } else {
- (*ret_thread) = init_thread(group);
+ return TM_ERROR_NONE;
}
- if ((*ret_thread)==NULL)
- {
- return TM_ERROR_OUT_OF_MEMORY;
- }
- return TM_ERROR_NONE;
+ (*ret_thread) = allocate_thread();
+ return (*ret_thread) == NULL ? TM_ERROR_OUT_OF_MEMORY : TM_ERROR_NONE;
+}
+//==============================================================================
+// Private functions
+
+/*
+ */
+static IDATA register_to_group(hythread_t thread, hythread_group_t group) {
+ IDATA status;
+ hythread_t cur, prev;
+
+ assert(thread);
+ assert(group);
+
+ // Acquire global TM lock to prevent concurrent acccess to thread list
+ status = hythread_global_lock(NULL);
+ if (status != TM_ERROR_NONE) return status;
+
+ thread_set_self(thread);
+ assert(thread == tm_self_tls);
+
+ thread->state = TM_THREAD_STATE_ALIVE | TM_THREAD_STATE_RUNNABLE;
+
+ if (!thread->thread_id) {
+ ++next_id;
+ thread->thread_id = next_id;
+ if (next_id >= MAX_ID) {
+ hythread_global_unlock(NULL);
+ return TM_ERROR_OUT_OF_MEMORY;
+ }
+ }
+
+ fast_thread_array[thread->thread_id] = thread;
+
+ thread->group = group;
+ group->threads_count++;
+ cur = group->thread_list->next;
+ prev = cur->prev;
+ thread->next = cur;
+ thread->prev = prev;
+ prev->next = cur->prev = thread;
+ return hythread_global_unlock(NULL);
}
/*
@@ -604,26 +618,20 @@
*
* @return created and initialized thread_t structure
*/
-static hythread_t init_thread(hythread_group_t group) {
+static hythread_t allocate_thread() {
apr_pool_t *pool;
- apr_status_t apr_status;
+ apr_status_t apr_status;
hythread_t ptr;
- IDATA status;
+ IDATA status;
- if (!group) {
- group = TM_DEFAULT_GROUP;
- }
+ apr_status = apr_pool_create(&pool, TM_POOL);
+ if((apr_status != APR_SUCCESS) || (pool == NULL)) return NULL;
- apr_status = apr_pool_create(&pool, group->pool);
- if((apr_status!=APR_SUCCESS)||(pool==NULL))
- return NULL;
ptr = (hythread_t )apr_pcalloc(pool, sizeof(HyThread));
- if (ptr==NULL)
- return NULL;
+ if (ptr == NULL) return NULL;
+
ptr->pool = pool;
- ptr->group = group;
ptr->os_handle = NULL;
- ptr->next = ptr->prev = ptr;
ptr->priority = HYTHREAD_PRIORITY_NORMAL;
// not implemented
//ptr->big_thread_local_storage = (void **)apr_pcalloc(pool, sizeof(void*)*tm_tls_capacity);
@@ -632,91 +640,94 @@
ptr->suspend_request = 0;
ptr->suspend_disable_count = 0;
status = hylatch_create(&ptr->join_event, 1);
- assert (status == TM_ERROR_NONE);
- status = hylatch_create(&ptr->safe_region_event, 1);
- assert (status == TM_ERROR_NONE);
+ assert (status == TM_ERROR_NONE);
+ status = hylatch_create(&ptr->safe_region_event, 1);
+ assert (status == TM_ERROR_NONE);
status = hysem_create(&ptr->resume_event, 0, 1);
- assert (status == TM_ERROR_NONE);
+ assert (status == TM_ERROR_NONE);
status = hysem_create(&ptr->park_event, 0, 1);
- assert (status == TM_ERROR_NONE);
+ assert (status == TM_ERROR_NONE);
status = hysem_create(&ptr->sleep_event, 0, 1);
- assert (status == TM_ERROR_NONE);
+ assert (status == TM_ERROR_NONE);
ptr->state = TM_THREAD_STATE_ALLOCATED;
- status = allocate_thread(ptr, group);
- if (status !=TM_ERROR_NONE)
- {
- return NULL;
- }
- group->threads_count++;
-
return ptr;
}
static void reset_thread(hythread_t thread) {
apr_status_t apr_status;
- IDATA status;
- apr_thread_join(&apr_status, thread->os_handle);
+ IDATA status;
+ if (thread->os_handle) {
+ apr_thread_join(&apr_status, thread->os_handle);
assert(!apr_status);
+ }
+
thread->os_handle = NULL;
thread->priority = HYTHREAD_PRIORITY_NORMAL;
// not implemented
//ptr->big_thread_local_storage = (void **)apr_pcalloc(pool, sizeof(void*)*tm_tls_capacity);
- thread->next = thread->prev = thread;
+
// Suspension
thread->suspend_request = 0;
thread->suspend_disable_count = 0;
status = hylatch_set(thread->join_event, 1);
- assert (status == TM_ERROR_NONE);
- status = hylatch_set(thread->safe_region_event, 1);
- assert (status == TM_ERROR_NONE);
+ assert (status == TM_ERROR_NONE);
+ status = hylatch_set(thread->safe_region_event, 1);
+ assert (status == TM_ERROR_NONE);
status = hysem_set(thread->resume_event, 0);
- assert (status == TM_ERROR_NONE);
+ assert (status == TM_ERROR_NONE);
status = hysem_set(thread->park_event, 0);
- assert (status == TM_ERROR_NONE);
+ assert (status == TM_ERROR_NONE);
status = hysem_set(thread->sleep_event, 0);
- assert (status == TM_ERROR_NONE);
+ assert (status == TM_ERROR_NONE);
thread->state = TM_THREAD_STATE_ALLOCATED;
- status =allocate_thread(thread, thread->group);
- if (status!=TM_ERROR_NONE)
- {
- thread=NULL;
- }
- thread->group->threads_count++;
}
// Wrapper around user thread start proc. Used to perform some duty jobs
// right after thread is started.
//////
static void* APR_THREAD_FUNC thread_start_proc(apr_thread_t* thd, void *p_args) {
- IDATA status;
- hythread_t thread = (hythread_t )p_args;
+ IDATA status;
+ hythread_t thread;
+ thread_start_proc_data * start_proc_data;
+
+ start_proc_data = (thread_start_proc_data *) p_args;
+ thread = start_proc_data->thread;
TRACE(("TM: native thread started: native: %p tm: %p", apr_os_thread_current(), thread));
+
+ status = register_to_group(thread, start_proc_data->group);
+ if (status != TM_ERROR_NONE) {
+ thread->exit_value = status;
+ return &thread->exit_value;
+ }
+
// Also, should it be executed under TM global lock?
thread->os_handle = thd; // DELETE?
- thread_set_self(thread);
status = hythread_set_priority(thread, thread->priority);
- //assert (status == TM_ERROR_NONE);//now we down - fixme
+ //assert (status == TM_ERROR_NONE);//now we down - fixme
thread->state |= TM_THREAD_STATE_RUNNABLE;
- // Do actual call of the thread body supplied by the user
- thread->start_proc(thread->start_proc_args);
+ // Do actual call of the thread body supplied by the user.
+ start_proc_data->start_proc(start_proc_data->start_proc_args);
- // shutdown sequence
+ // Shutdown sequence.
status = hythread_global_lock(NULL);
assert (status == TM_ERROR_NONE);
assert(hythread_is_suspend_enabled());
thread->state = TM_THREAD_STATE_TERMINATED | (TM_THREAD_STATE_INTERRUPTED & thread->state);
- // Send join event to those threads who called join on this thread
+ thread->exit_value = 0;
+
+ hythread_detach(thread);
+ // Send join event to those threads who called join on this thread.
hylatch_count_down(thread->join_event);
- status = thread_destroy(thread); // Remove thread from the list of thread
- assert (status == TM_ERROR_NONE);
- // Cleanup TLS after thread completes
- thread_set_self(NULL);
+
status = hythread_global_unlock(NULL);
- assert (status == TM_ERROR_NONE);
+ assert (status == TM_ERROR_NONE);
+
+ // TODO: It seems it is there is no need to call apr_thread_exit.
+ // Current thread should automatically exit upon returning from this function.
return (void *)(IDATA)apr_thread_exit(thd, APR_SUCCESS);
}
@@ -733,12 +744,8 @@
}
apr_pool_t* get_local_pool() {
- hythread_t self = tm_self_tls;
- if(self == NULL) {
- return TM_POOL;
- } else {
- return self->pool;
- }
+ hythread_t self = tm_self_tls;
+ return self == NULL ? TM_POOL : self->pool;
}
/**
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_state.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_state.c?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_state.c (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_state.c Mon Oct 9 09:01:52 2006
@@ -33,9 +33,7 @@
*
* @param[in] thread those attribute is read
*/
-int VMCALL hythread_is_alive(hythread_t thread) {
- return thread->state & TM_THREAD_STATE_ALIVE;
-};
+int VMCALL hythread_is_alive(hythread_t thread) { return thread->state & TM_THREAD_STATE_ALIVE ; };
/**
* Returns non-zero if thread is blocked on monitor enter.
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_suspend.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_suspend.c?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_suspend.c (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_suspend.c Mon Oct 9 09:01:52 2006
@@ -104,6 +104,11 @@
void VMCALL hythread_suspend_disable()
{
register hythread_t thread;
+#ifndef NDEBUG
+ // Check that current thread is in default thread group.
+ // Justification: GC suspends and enumerates threads from default group only.
+ assert(tm_self_tls->group == TM_DEFAULT_GROUP);
+#endif
#ifdef FS14_TLS_USE
__asm {
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h Mon Oct 9 09:01:52 2006
@@ -107,7 +107,7 @@
#endif
/**
- * get_local_pool() function return apr pool asociated with the current thread.
+ * get_local_pool() function return apr pool associated with the current thread.
* the memory could be allocated without lock using this pool
* dealocation should be done in the same thread, otherwise
* local_pool_cleanup_register() should be called
@@ -153,6 +153,9 @@
typedef struct HyThreadLibrary {
IDATA a;
+ hymutex_t TM_LOCK;
+ IDATA nondaemon_thread_count;
+ hycond_t nondaemon_thread_cond;
} HyThreadLibrary;
@@ -161,6 +164,12 @@
* Native thread control structure.
*/
typedef struct HyThread {
+
+ /**
+ * Each thread keeps a pointer to the libary it belongs to.
+ */
+ HyThreadLibrary * library;
+
// Suspension
/**
@@ -279,13 +288,7 @@
/**
* Hint for scheduler about thread priority
*/
- IDATA priority;
-
- /**
- * Is this thread daemon?
- */
- IDATA daemon;
-
+ IDATA priority;
// Monitors
@@ -306,17 +309,6 @@
*/
apr_threadattr_t *apr_attrs;
-
- /**
- * Procedure that describes thread body to be executed.
- */
- hythread_entrypoint_t start_proc;
-
- /**
- * Arguments to be passed to the thread body.
- */
- void *start_proc_args;
-
/**
* Array representing thread local storage
*/
@@ -400,6 +392,11 @@
*/
jobject thread_ref;
+ /**
+ * Is this thread daemon?
+ */
+ IDATA daemon;
+
} JVMTIThread;
@@ -603,18 +600,11 @@
* threads at shutdown.
*/
-IDATA countdown_nondaemon_threads();
-IDATA increase_nondaemon_threads_count();
-
-IDATA VMCALL hythread_create_with_group(hythread_t *ret_thread, hythread_group_t group, UDATA stacksize, UDATA priority, UDATA suspend, hythread_entrypoint_t func, void *data);
-
typedef void (*tm_thread_event_callback_proc)(void);
IDATA VMCALL set_safepoint_callback(hythread_t thread, tm_thread_event_callback_proc callback);
IDATA acquire_start_lock(void);
IDATA release_start_lock(void);
-
-IDATA thread_destroy(hythread_t thread);
IDATA thread_sleep_impl(I_64 millis, IDATA nanos, IDATA interruptable);
IDATA condvar_wait_impl(hycond_t cond, hymutex_t mutex, I_64 ms, IDATA nano, IDATA interruptable);
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h Mon Oct 9 09:01:52 2006
@@ -22,31 +22,40 @@
#ifndef _ENVIRONMENT_H
#define _ENVIRONMENT_H
-#include "tl/memory_pool.h"
+#include <apr_pools.h>
+#include <apr_thread_mutex.h>
+
+#include "open/hythread.h"
+#include "open/compmgr.h"
+#include "open/em_vm.h"
+
#include "String_Pool.h"
#include "vm_core_types.h"
#include "object_handles.h"
#include "jvmti_internal.h"
-#include "open/compmgr.h"
-#include "open/em_vm.h"
+#include "method_lookup.h"
typedef struct NSOTableItem NSOTableItem;
typedef struct DynamicCode DynamicCode;
typedef struct Assertion_Registry Assertion_Registry;
struct Global_Env {
- public:
- tl::MemoryPool& mem_pool; // memory pool
- String_Pool string_pool; // string table
+ public:
+ apr_pool_t* mem_pool; // memory pool
BootstrapClassLoader* bootstrap_class_loader;
- JavaVMInitArgs vm_arguments;
UserDefinedClassLoader* system_class_loader;
- Properties& properties;
+ Properties* properties;
DebugUtilsTI* TI;
NSOTableItem* nsoTable;
void* portLib; // Classlib's port library
DynamicCode* dcList;
Assertion_Registry* assert_reg;
+ Method_Lookup_Table* vm_methods;
+ hythread_library_t hythread_lib;
+ String_Pool string_pool; // string table
+ JavaVMInitArgs vm_arguments;
+
+
//
// globals
//
@@ -127,6 +136,7 @@
Class* java_lang_ExceptionInInitializerError_Class;
Class* java_lang_NullPointerException_Class;
Class* java_lang_StackOverflowError_Class;
+ Class* java_lang_ThreadDeathError_Class;
Class* java_lang_ClassNotFoundException_Class;
Class* java_lang_NoClassDefFoundError_Class;
@@ -137,7 +147,7 @@
Class* java_lang_ClassCastException_Class;
Class* java_lang_OutOfMemoryError_Class;
ObjectHandle java_lang_OutOfMemoryError;
-
+ ObjectHandle java_lang_ThreadDeathError;
// object of java.lang.Error class used for JVMTI JIT PopFrame support
ObjectHandle popFrameException;
@@ -163,8 +173,12 @@
VTable* JavaLangString_VTable;
Allocation_Handle JavaLangString_allocation_handle;
+ // Keeps uncaught exception for the thread which is destroying VM.
+ jthrowable uncaught_exception;
+
// Offset to the vm_class field in java.lang.Class;
unsigned vm_class_offset;
+
/**
* Shutting down state.
* 0 - working
@@ -172,7 +186,7 @@
* 2 - deadly errors in shutdown
*/
int shutting_down;
-
+
// FIXME
// The whole environemt will be refactored to VM instance
// The following contains a cached copy of EM interface table
@@ -180,12 +194,16 @@
OpenInstanceHandle em_instance;
OpenEmVmHandle em_interface;
- //
- // constructor
- //
- Global_Env(tl::MemoryPool& mm, Properties& prop);
- // function is used instead of destructor to uninitialize manually
- void EnvClearInternals();
+ Global_Env(apr_pool_t * pool);
+ ~Global_Env();
+
+ void * operator new(size_t size, apr_pool_t * pool) {
+ return apr_palloc(pool, sizeof(Global_Env));
+ }
+
+ void operator delete(void *) {}
+
+ void operator delete(void * mem, apr_pool_t * pool) {};
//
// determine bootstrapping of root classes
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/init.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/init.h?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/init.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/init.h Mon Oct 9 09:01:52 2006
@@ -25,24 +25,18 @@
#include "environment.h"
-bool vm_init(Global_Env *env);
-int run_java_main(char *classname, char **j_argv, int j_argc, Global_Env *p_env);
-int run_main_platform_specific(char *classname, char **j_argv, int j_argc, Global_Env *p_env);
+jint vm_attach_internal(JNIEnv ** p_jni_env, jthread * java_thread,
+ JavaVM * java_vm, jobject group,
+ char * name, jboolean daemon);
+jint vm_init1(JavaVM_Internal * java_vm, JavaVMInitArgs * vm_arguments);
+jint vm_init2(JNIEnv * jni_env);
+jint vm_destroy(JavaVM_Internal * java_vm, jthread java_thread);
+void vm_exit(int exit_code);
-JavaVMInitArgs* parse_cmd_arguments(int argc, char *argv[], char **class_name, char **jar_file, int *p_java_arg_num);
-void clear_vm_arguments(JavaVMInitArgs* vm_args);
void initialize_vm_cmd_state(Global_Env *p_env, JavaVMInitArgs* arguments);
void set_log_levels_from_cmd(JavaVMInitArgs* vm_arguments);
void parse_vm_arguments(Global_Env *p_env);
void parse_jit_arguments(JavaVMInitArgs* vm_arguments);
void print_generic_help();
-
-void create_vm(Global_Env *p_env, JavaVMInitArgs* vm_arguments);
-void destroy_vm(Global_Env *p_env);
-
-/*
- * declared in vm_main.cpp
- */
-extern Global_Env env;
#endif //_INIT_H
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jni_direct.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jni_direct.h?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jni_direct.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jni_direct.h Mon Oct 9 09:01:52 2006
@@ -20,44 +20,34 @@
*/
-
-
-
#ifndef _JNI_DIRECT_H_
#define _JNI_DIRECT_H_
-#include "jni.h"
+#include <apr_ring.h>
+#include <apr_pools.h>
+
#include "open/types.h"
-#include "Class.h"
-struct _jfieldID : public Field {
-};
+#include "jni.h"
+#include "Class.h"
-VMEXPORT jint JNICALL GetVersion(JNIEnv *env);
+typedef struct JavaVM_Internal JavaVM_Internal;
+typedef struct JNIEnv_Internal JNIEnv_Internal;
struct JavaVM_Internal : public JavaVM_External {
- JavaVM_Internal(const JNIInvokeInterface_ *_functions,
- Global_Env *_vm_env,
- void *_reserved) : vm_env(_vm_env), reserved(_reserved)
- {
- functions = _functions;
- }
- Global_Env* vm_env;
+ apr_pool_t * pool;
+ Global_Env * vm_env;
+ APR_RING_ENTRY(JavaVM_Internal) link;
void* reserved;
};
struct JNIEnv_Internal : public JNIEnv_External {
- JNIEnv_Internal(const JNINativeInterface_ *_functions,
- JavaVM_Internal *_vm,
- void *_reserved0) : vm(_vm), reserved0(_reserved0)
- {
- functions = _functions;
- }
JavaVM_Internal* vm;
void *reserved0;
};
-void jni_init();
+struct _jfieldID : public Field {
+};
jmethodID reflection_unreflect_method(JNIEnv *jenv, jobject ref_method);
jmethodID reflection_unreflect_constructor(JNIEnv *jenv, jobject ref_constructor);
@@ -606,7 +596,7 @@
VMEXPORT jlong JNICALL GetDirectBufferCapacity(JNIEnv* env, jobject buf);
-VMEXPORT jint JNICALL DestroyVM(JavaVM*);
+VMEXPORT jint JNICALL DestroyJavaVM(JavaVM*);
VMEXPORT jint JNICALL AttachCurrentThread(JavaVM*, void** penv, void* args);
VMEXPORT jint JNICALL DetachCurrentThread(JavaVM*);
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jni_utils.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jni_utils.h?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jni_utils.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jni_utils.h Mon Oct 9 09:01:52 2006
@@ -23,6 +23,7 @@
#ifndef _JNI_UTILS_H_
#define _JNI_UTILS_H_
+#include "environment.h"
#include "object_handles.h"
#include "platform.h"
#include "jni_direct.h"
@@ -39,7 +40,6 @@
VMEXPORT ClassLoaderHandle class_loader_lookup(jobject loader);
VMEXPORT void class_loader_load_native_lib(const char* lib, ClassLoaderHandle loader);
VMEXPORT ClassLoaderHandle class_loader_find_if_exists(jobject loader);
-VMEXPORT void class_loader_set_system_class_loader(ClassLoaderHandle);
VMEXPORT jvalue *get_jvalue_arg_array(Method *method, va_list args);
@@ -94,6 +94,9 @@
// internal VM function that provide Class searching functionality using
// String* parameter (instead of const char* in JNI FindClass)
jclass FindClass(JNIEnv* env_ext, String* name);
+
+JavaVM * jni_get_java_vm(JNIEnv * jni_env);
+Global_Env * jni_get_vm_env(JNIEnv * jni_env);
/* global handles */
extern ObjectHandle gh_jlc; //java.lang.Class
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/method_lookup.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/method_lookup.h?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/method_lookup.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/method_lookup.h Mon Oct 9 09:01:52 2006
@@ -86,7 +86,4 @@
}; //class Method_Lookup_Table
-VMEXPORT extern Method_Lookup_Table *vm_methods;
-
-
#endif //_METHOD_LOOKUP_H_
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/natives_support.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/natives_support.h?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/natives_support.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/natives_support.h Mon Oct 9 09:01:52 2006
@@ -60,9 +60,9 @@
/**
* Initializes natives_support module. Caller must provide thread safety.
*
- * @return Returns true if initialized successfully.
+ * @return Returns JNI_OK if initialized successfully.
*/
-bool
+jint
natives_init();
/**
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/properties.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/properties.h?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/properties.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/properties.h Mon Oct 9 09:01:52 2006
@@ -279,21 +279,6 @@
bucket = (Prop_entry**)STD_CALLOC(sizeof(Prop_entry*), size_);
iterator = new Iterator(this);
}
-#ifdef USE_MEM_MANAGER_FOR_ALLOCATION
-public:
- void *operator new(size_t sz, tl::MemoryPool& m) {
- return m.alloc(sz);
- }
- void operator delete(void *obj, tl::MemoryPool& m){
- //do nothing
- };
- void *operator new(size_t sz) {
- return m_malloc(sz);
- }
- void operator delete(void *obj){
- m_free(obj);
- };
-#endif
};
typedef struct _properties* PropertiesHandle;
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/thread_manager.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/thread_manager.h?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/thread_manager.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/thread_manager.h Mon Oct 9 09:01:52 2006
@@ -28,15 +28,8 @@
extern "C" {
#endif
-
-void vm_thread_shutdown();
-void vm_thread_init(Global_Env *p_env);
-
-void vm_thread_attach();
-void vm_thread_detach();
-
void free_this_thread_block(VM_thread *);
-VM_thread * get_a_thread_block();
+VM_thread * get_a_thread_block(JavaVM_Internal * java_vm);
extern volatile VM_thread *p_the_safepoint_control_thread; // only set when a gc is happening
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/version_svn_tag.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/version_svn_tag.h?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/version_svn_tag.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/version_svn_tag.h Mon Oct 9 09:01:52 2006
@@ -18,6 +18,6 @@
#ifndef _VERSION_SVN_TAG_
#define _VERSION_SVN_TAG_
-#define VERSION_SVN_TAG "453599"
+#define VERSION_SVN_TAG "454394"
#endif // _VERSION_SVN_TAG_
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_threads.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_threads.h?view=diff&rev=454411&r1=454410&r2=454411
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_threads.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_threads.h Mon Oct 9 09:01:52 2006
@@ -31,14 +31,18 @@
#include "vm_process.h"
#endif
+#include <apr_pools.h>
+
#include "open/types.h"
#include "open/hythread.h"
#include "open/ti_thread.h"
+
#include "vm_core_types.h"
#include "object_layout.h"
#include "open/vm_gc.h"
#include "exceptions_type.h"
#include "jvmti.h"
+#include "jni_direct.h"
//
@@ -66,9 +70,16 @@
class VM_thread {
public:
- // FIXME: workaround for strange bug. If this line is removed Visual Stidio
- // has corrupted list of modules and no debug info at all.
- void* system_private_data;
+ /**
+ * Memory pool where this structure is allocated.
+ * This pool should be used by current thread for memory allocations.
+ */
+ apr_pool_t * pool;
+
+ /**
+ * JNI environment associated with this thread.
+ */
+ JNIEnv_Internal * jni_env;
// In case exception is thrown, Exception object is put here
// TODO: Needs to be replaced with jobject!