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/08/23 18:49:21 UTC
svn commit: r434076 [17/18] - in /incubator/harmony/enhanced/drlvm/trunk:
build/make/components/ build/make/components/vm/ build/make/targets/
build/patches/lnx/ build/patches/lnx/APR/ build/patches/lnx/APR/threadproc/
build/patches/lnx/APR/threadproc/...
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/suspend.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/suspend.cpp?rev=434076&r1=434075&r2=434076&view=diff
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/suspend.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/suspend.cpp Wed Aug 23 09:48:41 2006
@@ -1,542 +0,0 @@
-/*
- * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
- *
- * Licensed 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: 1.1.2.3.4.4 $
- */
-
-
-#include "platform_lowlevel.h"
-#ifdef PLATFORM_POSIX
-#endif // PLATFORM_POSIX
-
-#include "open/gc.h"
-#include "jit_intf_cpp.h"
-#include "method_lookup.h"
-#include "vm_stats.h"
-#include "vm_threads.h"
-#include "thread_generic.h"
-#include "open/thread.h"
-#include "atomics.h"
-#include "root_set_enum_internal.h"
-#include "lock_manager.h"
-#include "verify_stack_enumeration.h"
-
-#include "open/vm_util.h"
-#include "vm_process.h"
-#include "cxxlog.h"
-
-#define REDUCE_RWBARRIER 1
-
-#if defined (PLATFORM_POSIX) && defined (_IPF_)
-extern "C" void get_rnat_and_bspstore(uint64* res);
-extern "C" void do_flushrs();
-#endif
-
-#ifdef REDUCE_RWBARRIER
-#if defined (PLATFORM_POSIX)
-#include <signal.h>
-#endif
-static void thread_yield_other(VM_thread*);
-#endif
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-
-// The rules for when something can and can't be enabled or disabled:
-//
-// 1. Only the current thread (p_TLS_vmthread) can disable and enable GC.
-// 2. You cannot enable GC from within JITTED code.
-// 3. You can only enable if you are disabled.
-
-// tmn_suspend_disable interface() assumes we are in enabled state (otherwise
-// tmn_suspend_disable_and_return_old_value() should be used)
-// so it would be better to rename thread_enable_suspend() to vm_try_enabling_gc()
-// to break incorrectly intuitive pair
-//
-// New interface:
-// tmn_suspend_enable();
-// tmn_suspend_disable();
-// the thread_safe_point();
-
-
-// this is internal function
-// thread param should always be self thread (p_TLS_vmthread).
-
-inline void thread_safe_point_impl(VM_thread *thread) {
- // must be either suspend enabled (status == 0) or in managed code (status == 1)
- assert(thread->suspend_enabled_status <= 1);
- debug_stack_enumeration();
- if(thread->suspend_request >0) {
- int old_status = thread->suspend_enabled_status;
- do {
- thread->suspend_enabled_status = 0;
- MemoryReadWriteBarrier();
- // code for Ipf that support StackIterator and immmediate suspend
- // notify suspender
- vm_set_event(thread->suspended_event);
- TRACE2("suspend", "suspended event... " << thread->thread_id);
-
- // wait for resume event
- vm_wait_for_single_object(thread->resume_event, INFINITE);
-
- TRACE2("suspend", "resuming after gc resume event" << thread->thread_id);
- thread->suspend_enabled_status = old_status;
- MemoryReadWriteBarrier();
- } while (thread->suspend_request >0);
- }
-} // thread_safe_point_impl
-
-
-void tmn_suspend_enable()
-{
- assert(p_TLS_vmthread->suspend_enabled_status == 1);
- tmn_suspend_enable_recursive();
-}
-
-void tmn_suspend_enable_recursive()
-{
- VM_thread *thread = p_TLS_vmthread;
- //TRACE2("suspend", "enable" << thread->suspend_enabled_status);
- assert(!tmn_is_suspend_enabled());
- debug_stack_enumeration();
- thread->suspend_enabled_status--;
- //assert(tmn_is_suspend_enabled());
-
-// MemoryReadWriteBarrier();
- if ((thread->suspend_request > 0)
- && (0 == thread->suspend_enabled_status)) {
- // notify suspender
- vm_set_event(thread->suspended_event);
- TRACE2("suspend", "suspended " << thread->thread_id);
- }
-}
-
-int suspend_count = 0;
-void tmn_suspend_disable()
-{
-// if (!tmn_is_suspend_enabled()) {
-// printf("asserted\n");
-// // the following lines allow MSVC++ "Debug->>>Break" to work
-// while (1) {
-// DWORD stat = vm_wait_for_single_object(NULL, 2000);
-//// if (stat == WAIT_OBJECT_0) break;
-//// assert(stat != WAIT_FAILED);
-// Sleep(2000);
-// }
-// }
-
- assert(tmn_is_suspend_enabled());
- tmn_suspend_disable_recursive();
-}
-
-void tmn_suspend_disable_recursive()
-{
-#ifdef _DEBUG
- suspend_count++;
- if(suspend_count % 100000 == 0)
- TRACE2("suspend", "suspend disable count: " << suspend_count);
-#endif
- VM_thread *thread = p_TLS_vmthread;
- //TRACE2("suspend", "disable: " << thread->suspend_enabled_status);
- thread->suspend_enabled_status++;
- debug_stack_enumeration();
-#ifndef REDUCE_RWBARRIER
- MemoryReadWriteBarrier();
-#endif
- if (1 == thread->suspend_enabled_status)
- thread_safe_point_impl(thread);
-}
-
-
-//FIXME replace through the code to tmn_suspend_disable();
-bool tmn_suspend_disable_and_return_old_value() {
- /*if(tmn_is_suspend_enabled()) {
- tmn_suspend_disable();
- return true;
- }
- return false;*/
- //TRACE2("suspend", "disable if enable: " << p_TLS_vmthread->suspend_enabled_status);
-
- p_TLS_vmthread->suspend_enabled_status++;
- return true;
-}
-
-VMEXPORT bool tmn_is_suspend_enabled() {
- assert(p_TLS_vmthread->suspend_enabled_status >=0);
- return (p_TLS_vmthread->suspend_enabled_status == 0);
-}
-
-// temporary for debug purpose
-VMEXPORT int tmn_suspend_disable_count() {
- return (p_TLS_vmthread->suspend_enabled_status);
-}
-
-void tmn_safe_point() {
- thread_safe_point_impl(p_TLS_vmthread);
-}
-
-void rse_thread_resume(VM_thread *thread)
-{
- if(thread == p_TLS_vmthread) {
- return;
- }
-
- if(thread->suspend_request <=0) {
- LOG2("suspend", "resume allived thread: " << thread->thread_id);
- return;
- }
-
- //decrement suspend_request
- if(--thread->suspend_request > 0) {
- return;
- }
-
- vm_set_event(thread->resume_event);
-
- TRACE2("suspend", "resume " << thread->thread_id);
- thread -> jvmti_thread_state ^= JVMTI_THREAD_STATE_SUSPENDED;
-
-} // rse_thread_resume
-
-// the function start suspension.
-// call wait_supend_respose() should be called to wait for safe region or safe point.
-// the function do not suspend self.
-static void send_suspend_request(VM_thread *t) {
-
- assert(t->suspend_request >=0);
- // already suspended?
- if(t->suspend_request > 0) {
- t->suspend_request++;
- return;
- }
-
- //we realy need to suspend thread.
-
- vm_reset_event(t->resume_event);
-
- t->suspend_request++;
- MemoryReadWriteBarrier();
-#ifdef REDUCE_RWBARRIER
- // ping other thread to do MemoryReadWriteBarrier()
- // this is done by sending signal on linux
- // or by SuspendThread();ResumeThread() on windows
- thread_yield_other(t);
-#endif
- TRACE2("suspend", "suspend request " << t->thread_id);
-}
-
-
-// the second part of suspention
-// blocked in case was selfsuspended.
-static void wait_supend_respose(VM_thread *t) {
- if(t->suspend_request > 1) {
- return;
- }
- if(t == p_TLS_vmthread) {
- TRACE2("suspend", "suspend self... skiped");
- return;
- }
-
- // we need to wait for notification only in case the thread is in the unsafe/disable region
- while (t->suspend_enabled_status != 0) {
- // wait for the notification
- TRACE2("suspend", "wait for suspended_event " << t->thread_id);
- vm_wait_for_single_object(t->suspended_event, 50);
- // this is auto reset event
- //vm_reset_event(t->suspended_event);
- }
- TRACE2("suspend", "suspended " << t->thread_id);
- t -> jvmti_thread_state |= JVMTI_THREAD_STATE_SUSPENDED;
-}
-
-
-// GC suspend function
-void suspend_all_threads_except_current() {
- VM_thread *self = p_TLS_vmthread;
- TRACE2("suspend", "suspend_all_threads_except_current() in thread: " << p_TLS_vmthread->thread_id);
- tm_acquire_tm_lock();
- // unlock mutex in case self was suspended by other thread
- // this will prevent us from cyclic dead-lock
- if(self != NULL) {
- while (self ->suspend_request > 0) {
- tm_release_tm_lock();
- TRACE2("suspend", "generic suspend safe_point " << self->thread_id);
- thread_safe_point_impl(self);
- tm_acquire_tm_lock();
- }
- }
- // Run through list of active threads and suspend each one of them.
- // We can do this safely because we hold the global thread lock
- VM_thread *t = p_active_threads_list;
- assert(t);
-
- for (;t;t = t->p_active) {
- if(t == self) {
- TRACE2("suspend", "skip enumerate self");
- continue;
- }
- send_suspend_request(t);
- }
-
- for (t = p_active_threads_list;t;t = t->p_active) {
- if(t == self) {
- TRACE2("suspend", "skip enumerate self");
- continue;
- }
- wait_supend_respose(t);
- t->gc_status = gc_at_safepoint;
-
- }
- tm_release_tm_lock();
-
- TRACE2("suspend", "suspend_all_threads_except_current() complete");
-}
-
-void suspend_all_threads_except_current_generic() {
- TRACE2("suspend", "suspend_all_threads_except_current() in thread: " << p_TLS_vmthread->thread_id);
- p_thread_lock->_lock_enum();
- // unlock mutex in case self was suspended by other thread
- // this will prevent us from cyclic dead-lock
- while (p_TLS_vmthread ->suspend_request > 0) {
- p_thread_lock->_unlock_enum();
- TRACE2("suspend", "generic suspend safe_point " << p_TLS_vmthread->thread_id);
- thread_safe_point_impl(p_TLS_vmthread);
- p_thread_lock->_lock_enum();
- }
- // Run through list of active threads and suspend each one of them.
- // We can do this safely because we hold the global thread lock
- VM_thread *t = p_active_threads_list;
- assert(t);
-
- for (;t;t = t->p_active) {
- if(t == p_TLS_vmthread) {
- TRACE2("suspend", "skip enumerate self");
- continue;
- }
- send_suspend_request(t);
- }
-
- for (t = p_active_threads_list;t;t = t->p_active) {
- if(t == p_TLS_vmthread) {
- TRACE2("suspend", "skip enumerate self");
- continue;
- }
- wait_supend_respose(t);
-
- }
- p_thread_lock->_unlock_enum();
-
- TRACE2("suspend", "suspend_all_threads_except_current() complete");
-}
-
-// GC resume function
-void resume_all_threads() {
- VM_thread *self = p_TLS_vmthread;
- tm_acquire_tm_lock();
- TRACE2("suspend", " ====== resume all threads ==========" );
-
- VM_thread *t = p_active_threads_list;
- assert(t);
-
-
- for (;t;t = t->p_active) {
- if(t == self) {
- assert(t->gc_status == gc_enumeration_done);
- t->gc_status = zero;
- continue;
- }
- rse_thread_resume(t);
- assert(t->gc_status == gc_enumeration_done);
- t->gc_status = zero;
-
- }
- tm_release_tm_lock();
-
-}
-
-void resume_all_threads_generic() {
- p_thread_lock->_lock_enum();
- TRACE2("suspend", " ====== resume all threads ==========" );
-
- VM_thread *t = p_active_threads_list;
- assert(t);
-
-
- for (;t;t = t->p_active) {
- if(t == p_TLS_vmthread) {
- continue;
- }
-
- if ((t->suspend_request == 1 && t->gc_status != zero) // do no resume stoped by GC thread
- || t->suspend_request <=0) { // do not resume working thread
-
- TRACE2("suspend", "generic resume failed " << t->thread_id << " gc " <<t->gc_status
- << " suspend_request " << t->suspend_request );
- continue;
- }
-
- rse_thread_resume(t);
- }
- p_thread_lock->_unlock_enum();
-}
-
-void
-thread_suspend_self() {
- TRACE2("suspend", "suspend_self called" );
- VM_thread *thread = p_TLS_vmthread;
- assert(thread);
- tm_acquire_tm_lock();
- send_suspend_request(thread);
- tm_release_tm_lock();
-
- assert(tmn_is_suspend_enabled());
- assert(thread->suspend_request > 0);
- thread_safe_point_impl(thread);
-}
-
-bool
-thread_suspend_generic(VM_thread *thread)
-{
- VM_thread *self = p_TLS_vmthread;
- // suspend self
- if(thread == NULL || thread == self) {
- TRACE2("suspend", "suspend self " << (thread == NULL?0:thread->thread_id));
- thread_suspend_self();
- return true;
- }
-
- assert(tmn_is_suspend_enabled());
- tm_acquire_tm_lock();
-
- // unlock mutex in case self was suspended by other thread
- // this will prevent us from cyclic dead-lock
- if(self != NULL) {
- while (self ->suspend_request > 0) {
- tm_release_tm_lock();
- TRACE2("suspend", "generic suspend safe_point " << self->thread_id);
- thread_safe_point_impl(self);
- tm_acquire_tm_lock();
- }
- }
- TRACE2("suspend", "generic suspend " << thread->thread_id);
-
- send_suspend_request(thread);
- wait_supend_respose(thread);
- tm_release_tm_lock();
- return true;
-} // thread_suspend_generic
-
-
-bool
-thread_resume_generic(VM_thread *t)
-{
- if(t == NULL || t == p_TLS_vmthread) {
- TRACE2("suspend", "generic resume self failed ");
- return false;
- }
- assert(tmn_is_suspend_enabled());
- TRACE2("suspend", "generic resume " << t->thread_id);
-
- tm_acquire_tm_lock();
- assert(t);
- assert(t->suspend_request >=0);
- if ((t->suspend_request == 1 && t->gc_status != zero) // do no resume stoped by GC thread
- || t->suspend_request <=0) { // do not resume working thread
-
- TRACE2("suspend", "generic resume failed " << t->thread_id << " gc " <<t->gc_status
- << " suspend_request " << t->suspend_request );
- tm_release_tm_lock();
- return false;
- }
-
- rse_thread_resume(t);
- tm_release_tm_lock();
- return true;
-} // thread_resume_generic
-
-void jvmti_thread_resume(VM_thread *thread)
-{
- thread_resume_generic(thread);
-} // jvmti_thread_resume
-
-
-#ifdef REDUCE_RWBARRIER
-// touch thread to flash memory
-static void thread_yield_other(VM_thread* thread) {
- assert(thread);
- TRACE2("suspend", "yield from thread: " << p_TLS_vmthread->thread_id << "to: " << thread->thread_id);
- // use signals on linux
- #ifdef PLATFORM_POSIX
- // IPF compiler generate st4.rel ld4.acq for valatile variables
- // so nothing need to do.
- #ifndef _IPF_
- assert(thread->thread_id);
- pthread_kill(thread->thread_id, SIGUSR2);
- sem_wait(&thread->yield_other_sem);
- #endif
- // use SuspendThread on windows
- #else
- SuspendThread(thread->thread_handle);
- ResumeThread(thread->thread_handle);
- #endif
-}
-#endif
-
-// depricated functions
-uint32 thread_gc_number_of_threads()
-{
- uint32 xx = 0;
-
- tmn_suspend_enable(); // to make tm_iterator_create()happy: it uses assert(tmn_is_suspend_enabled());
- tm_iterator_t * iterator = tm_iterator_create();
- tmn_suspend_disable();
-
- VM_thread *thread = tm_iterator_next(iterator);
- while (thread != NULL) {
- xx++;
- thread = tm_iterator_next(iterator);
- }
- tm_iterator_release(iterator);
-
- // do NOT enumerate the current thread thus its
- // return xx - 1; instead of return xx;
- // setup iterator for thread_gc_enumerate_one();
- p_threads_iterator = p_active_threads_list;
-
- return xx - 1;
-}
-
-//TODO change to iterator
-VM_thread *thread_gc_enumerate_one()
-{
- //depricated
-
- assert(p_threads_iterator);
-
- // skip over the current thread which is already at
- // a gc safepoint. Also, doing a Get/SetThreadContext()
- // on the current thread will cause a crash (for good reason)
-
- if(p_TLS_vmthread == p_threads_iterator)
- p_threads_iterator = p_threads_iterator->p_active;
-
- VM_thread *p_cookie = p_threads_iterator;
- if(p_threads_iterator)
- p_threads_iterator = p_threads_iterator->p_active;
-
- return p_cookie;
-}
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_dump.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_dump.cpp?rev=434076&r1=434075&r2=434076&view=diff
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_dump.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_dump.cpp Wed Aug 23 09:48:41 2006
@@ -27,7 +27,7 @@
#include "jni_utils.h"
#include "jit_intf_cpp.h"
#include "dll_jit_intf.h"
-#include "open/thread.h"
+
#include "object_generic.h"
#include "root_set_enum_internal.h"
#include "lock_manager.h"
@@ -38,7 +38,6 @@
static std::set<void *> unique_references;
-static int stack_key;
enum reference_types {
root_reference = 1,
@@ -47,493 +46,26 @@
managed_reference_with_base
};
-static void td_print_thread_dumps(FILE* f);
+ void td_print_thread_dumps(FILE* f);
#ifdef _DEBUG
-static void td_print_native_dumps(FILE* f);
-#endif
-static void td_attach_thread(void( *printer)(FILE *), FILE *out);
-
-/**
- * The thread dump entry poin, this function being called from the signal handler
- */
-void td_dump_all_threads(FILE *out) {
-#ifdef _DEBUG
- td_print_native_dumps(out);
-#endif
- td_attach_thread(td_print_thread_dumps, out);
-}
-
-/**
- * Attaches current thread to vm and runs the given "Thread dump" thread function.
- */
-static void td_attach_thread(void( *printer)(FILE *), FILE *out) {
- VM_thread *current;
- current = get_a_thread_block();
-
- if (NULL == current) {
- WARN("Thread dump: can't get a thread block");
- return;
- }
-
- p_thread_lock->_lock_enum();
-
- set_TLS_data(current);
- #ifdef PLATFORM_POSIX
- current->thread_handle = getpid();
- //MVM
- current->thread_id = GetCurrentThreadId();
+ void td_print_native_dumps(FILE* f);
#endif
- tmn_suspend_enable();
-
- {
- NativeObjectHandles lhs;
- gc_thread_init(¤t->_gc_private_information);
-
- printer(out);
- }
-
- free_this_thread_block(current);
- set_TLS_data(NULL);
- gc_thread_kill(¤t->_gc_private_information);
- p_thread_lock->_unlock_enum();
-}
-
-/**
- * Returns java.lang.Thread pointer associated with te given VM_thread
- */
-static jthread get_jthread(VM_thread * thread) {
- if (thread->p_java_lang_thread) {
- tmn_suspend_enable();
- ObjectHandle hThread = oh_allocate_global_handle();
- tmn_suspend_disable();
- hThread->object = (struct ManagedObject *)thread->p_java_lang_thread;
-
- tmn_suspend_enable();
-
- return (jthread)hThread;
- } else {
- return NULL;
- }
-}
-
-/**
- * Prints monitors owned by the currently processed thread.
- * During stack traversing JIT being called for live object enumeration. Object returned,
- * being checked if their "lockword" contains thread key of the current thread. Those objects which
- * maches being collected in the unique references set.
- *
- * This function prints objects collected and frees the set for the next thread;
- */
-static void td_print_owned_monitors(FILE *out) {
- if (unique_references.size()) {
- std::set<void *>::const_iterator it;
- fprintf(out, "Thread owns following monitors:\n");
- ObjectHandle jmon = oh_allocate_local_handle();
- ObjectHandle jmon_class = oh_allocate_local_handle();
- for (it = unique_references.begin(); it != unique_references.end(); it++) {
- ManagedObject *p_obj = (ManagedObject *)*it;
-
- tmn_suspend_disable(); //---------------------------------v
- jmon_class->object = struct_Class_to_java_lang_Class(p_obj->vt()->clss);
- jmon->object = p_obj;
- tmn_suspend_enable(); //---------------------------------^
-
-
- JNIEnv *jenv = (JNIEnv *)jni_native_intf;
- jmethodID mon_name = jenv -> GetMethodID(jmon_class, "getName","()Ljava/lang/String;");
- jstring _mon_name = jenv -> CallObjectMethod (jmon, mon_name);
- char *class_name = (char *)jenv -> GetStringUTFChars (_mon_name, false);
-
- fprintf(stderr, " - %s@0x%ld\n", class_name, generic_hashcode(p_obj));
- }
-
- unique_references.clear();
- }
-
-}
-
-/**
- * Prints symbolic name for the given numeric java state.
- */
-static char *print_thread_state(java_state state) {
- static char *names[8] = {"zip",
- "sleeping",
- "waiting",
- "timed_waiting",
- "birthing",
- "running",
- "blocked",
- "dying"};
-
- return names[state];
-}
-
-/**
- * checks if the thread is alive.
- * Note:
- * Only alive threads being processed during the thread dump.
- */
-static int td_is_alive(VM_thread *thread) {
- if ( !thread ) {
- return 0; // don't try to isAlive() non-existant thread
- }
-
- if (thread->app_status == zip) {
- return 0; // don't try to isAlive() non-existant thread
- }
- java_state as = thread->app_status;
-
- // According to JAVA spec, this method should return true, if and
- // only if the thread has been started and not yet died.
- switch (as) {
- case thread_is_sleeping:
- case thread_is_waiting:
- case thread_is_timed_waiting:
- case thread_is_blocked:
- case thread_is_running:
- return 1;
- case thread_is_dying:
- case thread_is_birthing:
- return 0;
- default:
- return 0;
- }
-}
-
-/**
- * Print java.lang.Thread info in the following format:
- * "<thread name>" prio=<thread priority> id=<thread id> <java state>
- * ^--- <monitor name> - if blocked or waiting
- *
- * Returns true if jthread header was successfully printed;
- */
-static bool td_print_java_thread_info(FILE *f, VM_thread *thread, bool *is_header_printed) {
- static JNIEnv *jenv = (JNIEnv *)jni_native_intf;
- static jclass cl = jenv -> FindClass("java/lang/Thread");
- static jmethodID method_name = jenv -> GetMethodID(cl, "getName","()Ljava/lang/String;");
- static jmethodID method_prio = jenv -> GetMethodID(cl, "getPriority","()I");
-
-
- jthread _jthread = get_jthread(thread);
- if (!_jthread) {
- return false;
- } else {
- if (!*is_header_printed) {
- *is_header_printed = true;
- fprintf(f,"=== FULL THREAD DUMP\n");
- }
- }
-
- jstring name = jenv -> CallObjectMethod (_jthread, method_name);
- char *_name = (char *)jenv -> GetStringUTFChars (name, false);
- jint prio = jenv -> CallIntMethod(_jthread, method_prio);
- java_state thread_st = thread->app_status;
-
- fprintf(f,"\"%s\" prio=%d id=0x%lX skey=0x%lX %s\n",
- _name, prio, (long)thread->thread_id, thread->stack_key, print_thread_state(thread_st));
-
- if (thread_st == 2
- || thread_st == 3
- || thread_st == 6) {
- //blocked/waiting on monitor
- ////
- ManagedObject *p_mon = mon_enter_array[thread->thread_index].p_obj;
- if (p_mon) {
- ObjectHandle jmon = oh_allocate_local_handle();
- ObjectHandle jmon_class = oh_allocate_local_handle();
- tmn_suspend_disable(); //---------------------------------v
- jmon_class->object= struct_Class_to_java_lang_Class(p_mon->vt()->clss);
- jmon->object = p_mon;
- tmn_suspend_enable(); //---------------------------------^
-
-
- jmethodID mon_name = jenv -> GetMethodID(jmon_class, "getName","()Ljava/lang/String;");
- jstring _mon_name = jenv -> CallObjectMethod (jmon, mon_name);
- char *class_name = (char *)jenv -> GetStringUTFChars (_mon_name, false);
-
- fprintf(f,"^--- %s on monitor : %s@%lx\n", print_thread_state(thread_st), class_name, generic_hashcode(p_mon));
- }
- }
- return true;
-}
-
-/**
- * Prints stack trace entry in the following format:
- *
- * at <class name>.<method name><method descripto>(<source info>)@<instruction pointer>,
- *
- * where source info is on of the following:
- * - <java source file name>:<line number>
- * - Native source
- * - Unknown source
- */
-static void td_print_entry(FILE *f, Method_Handle m, int ip, bool is_native) {
- const char *file_name;
-
- fprintf(f, " at %s.%s%s(", class_get_name(method_get_class(m)), method_get_name(m), method_get_descriptor(m));
-
- if (is_native) {
- fprintf(f,"Native Method)\n");
- } else {
- file_name = class_get_source_file_name(method_get_class(m));
-
- if (file_name) {
- fprintf(f,"%s : %d", file_name, m->get_line_number((uint16)ip));
- } else {
- fprintf(f,"Unknown Source");
- }
- fprintf(f,")@0x%X\n", ip);
- }
-}
-
-
-static void td_print_thread_dumps(FILE* f) {
- bool print_footer = false;
- suspend_all_threads_except_current_generic();
- VM_thread *thread = p_active_threads_list;
-
-
- while(thread) {
- if (!(td_is_alive(thread) && td_print_java_thread_info(f, thread, &print_footer))) {
- thread = thread->p_active;
- continue;
- }
-
- stack_key = thread->stack_key;
- StackIterator* si = si_create_from_native(thread);
- unsigned depth = 0;
-
- while (!si_is_past_end(si)) {
- Method_Handle m = get_method(si);
- if (m) {
- CodeChunkInfo* cci = si_get_code_chunk_info(si);
- if ( cci != NULL ) {
- cci->get_jit()->get_root_set_for_thread_dump(cci->get_method(), 0, si_get_jit_context(si));
- uint32 inlined_depth = si_get_inline_depth(si);
- uint32 offset = (POINTER_SIZE_INT)si_get_ip(si) - (POINTER_SIZE_INT)cci->get_code_block_addr();
-
- for (uint32 i = 0; i < inlined_depth; i++) {
- Method *real_method = cci->get_jit()->get_inlined_method(cci->get_inline_info(), offset, i);
-
- td_print_entry(f, real_method, offset, false);
- depth++;
- }
- }
-
- td_print_entry(f, m, (uint8*)si_get_ip(si) - (uint8*)((Method *)m)->get_byte_code_addr(), si_is_native(si));
- }
-
- depth++;
- si_goto_previous(si);
- }
- si_free(si);
-
- td_print_owned_monitors(f);
-
- fprintf(f, "--- End Stack Trace (0x%X, depth=%d)\n\n", thread, depth);
- thread = thread->p_active;
-
- }
-
- if (print_footer) fprintf(f,"=== END OF THREAD DUMP\n\n");
- resume_all_threads_generic();
-}
+ void td_attach_thread(void( *printer)(FILE *), FILE *out);
VMEXPORT void vm_check_if_monitor(void **reference,
- void **reference_base,
+ void **base_reference,
uint32 *compressed_reference,
int slotOffset,
Boolean pinned,
int type) {
-
- ManagedObject *p_obj = NULL;
-
- if (!(type>0 && type<5)) return;
-
- switch((reference_types)type) {
- case root_reference: {
- if (reference) {
- p_obj = (ManagedObject *)*reference;
- }
- break;
- }
-
- case compresses_root_reference: {
- COMPRESSED_REFERENCE cref = *compressed_reference;
- ManagedObject* obj = (ManagedObject *)uncompress_compressed_reference(cref);
- if (cref != 0
- && (((POINTER_SIZE_INT)Class::heap_base <= (POINTER_SIZE_INT)obj)
- && ((POINTER_SIZE_INT)obj <= (POINTER_SIZE_INT)Class::heap_end))
- ) {
- p_obj = obj;
- }
- break;
- }
-
- case managed_reference_with_base: {
- slotOffset = (int)(POINTER_SIZE_INT)(*((Byte**)reference)-*((Byte**)reference_base));
-
- }
-
- case managed_reference: {
- p_obj = (ManagedObject *)((Byte*)*reference - slotOffset);
- break;
- }
-
- default : return;
- }
-
- if (p_obj) {
- uint16 *sk = P_STACK_KEY(p_obj);
-
- if(stack_key == *sk) {
- unique_references.insert(p_obj);
- }
- }
}
+/**
+ * The thread dump entry poin, this function being called from the signal handler
+ */
+void td_dump_all_threads(FILE *out) {
#ifdef _DEBUG
-
-char* get_lock_name(void* lock) {
- if(p_thread_lock == lock) {
- return "p_thread_lock";
- }
- if(p_jit_a_method_lock == lock) {
- return "p_jit_a_method_lock";
- }
- if(p_vtable_patch_lock == lock) {
- return "p_vtable_patch_lock";
- }
- if(p_meth_addr_table_lock == lock) {
- return "p_meth_addr_table_lock";
- }
- if(p_method_call_lock == lock) {
- return "p_method_call_lock";
- }
- if(p_tm_lock == lock) {
- return "p_tm_lock";
- }
- if (JAVA_CODE_PSEUDO_LOCK == lock) {
- return "java_code";
- }
- return "unknown";
-}
-
-int get_lock_priority(void* lock) {
- if(p_thread_lock == lock) {
- return 10;
- }
- if(p_vtable_patch_lock == lock) {
- return 30;
- }
- if(p_meth_addr_table_lock == lock) {
- return 40;
- }
-
- if(p_method_call_lock == lock) {
- return 50;
- }
- if(p_jit_a_method_lock == lock) {
- return 55;
- }
- if (JAVA_CODE_PSEUDO_LOCK == lock) {
- return 70;
- }
- return -1;
-}
-
-
-void check_lock_order(VM_thread *thread) {
- if (!thread) {
- INFO("Cannot check lock order without a thread block");
- return;
- }
-
- int lock_id = thread->locks_size-1;
- if(lock_id < 1) {
- return;
- }
- void *last_lock = thread->locks[thread->locks_size-1];
- if(get_lock_priority(last_lock) == -1) {
- return;
- }
-
- int lock_priority;
- void *prev_lock;
- for (lock_id= lock_id-1; lock_id >=0; lock_id--) {
- prev_lock = thread->locks[lock_id];
- lock_priority = get_lock_priority(prev_lock);
- if(lock_priority !=-1 && get_lock_priority(last_lock) > get_lock_priority(prev_lock)) {
- LOG2("deadlock", "possible deadlock (incorrect lock order):" << get_lock_name(last_lock) << " after " << get_lock_name(prev_lock) );
- }
- }
-
-}
-
-void push_lock(VM_thread *thread, void* lock)
-{
- if (!thread) {
- INFO("Attempt to push " << get_lock_name(lock) << " without a thread block");
- return;
- }
-
- TRACE("Thread " << thread->thread_handle << " acquired " << get_lock_name(lock) << " lock");
- //assert(thread->contendent_lock == lock);
- thread->contendent_lock = NULL;
- thread->locks[thread->locks_size++] = lock;
- ASSERT(thread->locks_size < MAX_THREAD_LOCKS, "Debugging lock stack overflowed. Last locks: " \
- << get_lock_name(thread->locks[thread->locks_size - 1]) << ", " \
- << get_lock_name(thread->locks[thread->locks_size - 2]) << ", " \
- << get_lock_name(thread->locks[thread->locks_size - 3]) << ", " \
- << get_lock_name(thread->locks[thread->locks_size - 4]));
-
- check_lock_order(thread);
-
-}
-
-void pop_lock(VM_thread *thread, void* lock) {
- if (!thread) {
- INFO("Attempt to pop " << get_lock_name(lock) << " without a thread block");
- return;
- }
- TRACE("Thread " << thread->thread_handle << " released " << get_lock_name(lock) << " lock");
- ASSERT(thread->locks_size > 0, "Lock stack is empty, unexpected unlock " << get_lock_name(lock));
-
- void *res = thread->locks[--thread->locks_size];
- ASSERT(res == lock, "Incorrect order, expected unlocking " << get_lock_name(res) \
- << " before unlocking " << get_lock_name(lock) << ", thread block is " << thread);
-}
-
-void contends_lock(VM_thread *thread, void* lock) {
- if (!thread) {
- INFO("Attempt to contend on " << get_lock_name(lock) << " without a thread block");
- return;
- }
-
- //assert(thread->contendent_lock == NULL);
- thread->contendent_lock=lock;
-}
-
-static void td_print_native_dumps(FILE* f) {
- VM_thread *thread = p_active_threads_list;
- fprintf (f, "Native thread locks dump:\n");
- while(thread) {
- fprintf(f, "thread %ld locks:", thread->thread_id);
- if(thread->suspend_enabled_status) {
- fprintf(f, " suspend_disabled%d, ", thread->suspend_enabled_status);
- if(thread->suspend_request) {
- fprintf(f, " suspend_request = %d, ", thread->suspend_request);
- }
- }
- for (int i= 0; i < thread->locks_size; i++) {
- fprintf(f, "%s, ", get_lock_name(thread->locks[i]));
- }
- if(thread->contendent_lock) {
- fprintf(f, "\n\t contends on %s\n", get_lock_name(thread->contendent_lock));
- } else {
- fprintf(f, "\n");
- }
- thread = thread->p_active;
- }
-}
+// td_print_native_dumps(out);
#endif
+ // td_attach_thread(td_print_thread_dumps, out);
+}
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp?rev=434076&r1=434075&r2=434076&view=diff
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp Wed Aug 23 09:48:41 2006
@@ -41,6 +41,7 @@
#include <unistd.h>
#endif
+#include "open/thread_externals.h"
#include "environment.h"
#include "vm_strings.h"
#include "open/types.h"
@@ -60,7 +61,7 @@
#include "vm_threads.h"
#include "jni_utils.h"
#include "object.h"
-#include "open/thread.h"
+
#include "platform_core_natives.h"
#include "heap.h"
#include "verify_stack_enumeration.h"
@@ -83,7 +84,7 @@
#include "thread_manager.h"
#include "object_generic.h"
#include "thread_generic.h"
-#include "open/thread.h"
+
#include "mon_enter_exit.h"
#include "jni_direct.h"
@@ -96,845 +97,78 @@
#include "../m2n_ia32_internal.h"
#endif
-void __cdecl call_the_run_method2(void *p_xx);
+#include "port_malloc.h"
-int next_thread_index = 1; // never use zero for a thread index
+#include "open/jthread.h"
/////////////////////////////////////////////////////////////////////
// Native lib stuff
-#if defined (__INTEL_COMPILER)
-#pragma warning( push )
-#pragma warning (disable:1683) // to get rid of remark #1683: explicit conversion of a 64-bit integral type to a smaller integral type
-#endif
-
-void set_vm_thread_ptr_safe(JNIEnv *jenv, jobject jThreadObj, jlong data)
-{
- jclass jthreadclass = jenv->GetObjectClass(jThreadObj);
- jfieldID field_id = jenv->GetFieldID(jthreadclass, "vm_thread", "J");
- jenv->SetLongField(jThreadObj, field_id, data);
-}
-
-VM_thread *get_vm_thread_ptr_safe(JNIEnv *jenv, jobject jThreadObj)
-{
- jclass jThreadClass = jenv->GetObjectClass(jThreadObj);
- jfieldID field_id = jenv->GetFieldID(jThreadClass, "vm_thread", "J");
- POINTER_SIZE_INT data = (POINTER_SIZE_INT)jenv->GetLongField(jThreadObj, field_id);
-
- return (VM_thread *)data;
-}
-
-// ToDo: Remove this function. Use get_vm_thread_ptr_safe() instead.
-static VM_thread *
-my_get_vm_thread_ptr_safe(JNIEnv *jenv, jobject jThreadObj)
-{
- jclass jThreadClass = jenv->GetObjectClass(jThreadObj);
- jfieldID field_id = jenv->GetFieldID(jThreadClass, "vm_thread", "J");
- POINTER_SIZE_INT eetop = (POINTER_SIZE_INT)jenv->GetLongField(jThreadObj, field_id);
- return (VM_thread *)eetop;
-} //my_get_vm_thread_ptr_safe
-
-static boolean is_daemon_thread(JNIEnv *jenv, jobject jThreadSelf)
-{
- //FIXME should not use JNI here
- jclass jthreadclass = jenv->GetObjectClass(jThreadSelf);
- jfieldID daemon_id = jenv->GetFieldID(jthreadclass, "daemon", "Z");
- jboolean daemon = jenv->GetBooleanField(jThreadSelf, daemon_id);
- return daemon ? TRUE : FALSE;
-} //is_daemon_thread
-
-// Call default constructor for java.lang.Thread object (should be called for main thread)
-static bool init_thread_object(JNIEnv *jenv, jobject jthread)
-{
- // DRL uses this function to initialize main thread's java.lang.Thread object.
- jclass tclazz = FindClass(jenv, "java/lang/Thread");
- assert(tclazz);
-
- jmethodID tconstr = GetMethodID(jenv, tclazz, "<init>", "()V");
- assert(tconstr);
-
- CallVoidMethod(jenv, jthread, tconstr);
-
- if (ExceptionOccurred(jenv)) {
- WARN("*** Error: exception occured in main Thread constructor.");
- ExceptionDescribe(jenv);
- ExceptionClear(jenv);
- return false;
- }
-
- return true;
-} //init_thread_object
-
-void thread_sleep(jthread UNREF thread, long millis, int UNREF nanos){
- Java_java_lang_Thread_sleep_generic(jni_native_intf, get_thread_ptr(), millis);
-}
-
-//JNI implementation of Thread.sleep()
-void Java_java_lang_Thread_sleep_generic(JNIEnv *jenv, VM_thread * p_thr, int64 msec)
-{
- assert(!((unsigned int)(msec >> 32))); // We currently ignore high 32 bits of msec.
-
- tm_acquire_tm_lock();
-
- jint stat;
-
- stat = vm_reset_event(p_thr->event_handle_notify_or_interrupt); // throw away old vm_set_event()s
- assert(stat);
-
- assert(p_thr->app_status == thread_is_running);
- p_thr->app_status = thread_is_sleeping;
-
- tm_release_tm_lock();
-
- assert(tmn_is_suspend_enabled());
- p_thr -> is_suspended = true;
-
- while (p_thr->interrupt_a_waiting_thread == false) {
- stat = vm_wait_for_single_object(p_thr->event_handle_notify_or_interrupt, (int)msec);
-
- if (stat == WAIT_TIMEOUT)
- {
-#ifdef _DEBUG
- total_sleep_timeouts++;
-#endif
- break;
- }
-
- // the sleep did not time out and nobody sent us an interrupt
- // the only other possibility is that this is a stale notify/notifyAll()
- //
- // if other threads did a notify()/notifyAll() and between
- // the time they selected the current thread and the time they
- // do the notifyAll's vm_set_event(), they get preempted for a long enough period of
- // time such that the current thread gets to the above WaitForSingleEvent()
- // then we ignore this unblocking and loop back to the waitforsingleevent()
- // note that we re-wait for the same amount of msec. This should not cause a problem
- // since pre-emptive multitasking guarantees a sleep() will be at least
- // mseconds or longer. If the system is lightly loaded, the stale notify()s will
- // get flushed out quickly. If the system is heavily loaded, the run queues
- // are long meaning a sleep will wakeup and go onto a long run queue anyway
- }
- p_thr -> is_suspended = false;
- tmn_suspend_disable(); // to suspend thread if needed
- tmn_suspend_enable();
-
- tm_acquire_tm_lock();
- assert(p_thr->app_status == thread_is_sleeping);
- p_thr->app_status = thread_is_running;
-
- if (p_thr->interrupt_a_waiting_thread == true)
- {
- // this can only happen if someone really did send us an interrupt
- p_thr->interrupt_a_waiting_thread = false;
-#ifdef _DEBUG
- total_sleep_interrupts++;
-#endif
- tm_release_tm_lock();
- throw_exception_from_jni(jenv, "java/lang/InterruptedException", 0);
- return; // gregory - added return here because otherwise we execute
- // unlock_enum twice which results in error and failed assert on
- // error code from pthread_mutex_unlock that thread doesn't own
- // the mutex. The thread doesn't own mutex because it was unlocked in
- // this if block
- }
-
- tm_release_tm_lock();
-}
-
-#if defined (__INTEL_COMPILER)
-#pragma warning( pop )
-#endif
-
-void Java_java_lang_Thread_interrupt_generic(VM_thread *p_thr)
-{
- if (!p_thr) {
- printf("bad interrupt, current thread_index = %d\n", p_TLS_vmthread->thread_index);
- return;
- }
-
- p_thr->interrupt_a_waiting_thread = true;
- unpark(p_thr);
-
- jint UNUSED stat = vm_set_event(p_thr->event_handle_notify_or_interrupt);
- assert(stat);
-}
-
-void Java_java_lang_Thread_setPriority_generic(VM_thread *p_vm_thread, int pri)
-{
-
- tm_acquire_tm_lock();
- tmn_suspend_disable();
-
- ASSERT(0, "Is not expected to be called");
- // NOTE: setPriority is actually called before the thread is started
- // in which case, p_vm_thread is null... Thread_start will then set the priority
-
- if(p_vm_thread == 0) {
- tmn_suspend_enable();
- tm_release_tm_lock();
- return;
- }
- if (p_vm_thread->app_status == zip) {
- tmn_suspend_enable();
- tm_release_tm_lock();
- return;
- }
-
- int status = p_vm_thread->setPriority(THREAD_PRIORITY_NORMAL + pri - 5);
- if(status == 0) {
- jint error = IJGetLastError();
- printf ("java_lang_Thread_setPriority error = 0x%x\n", error);
- }
-
- tmn_suspend_enable();
- tm_release_tm_lock();
-} //Java_java_lang_Thread_setPriority_generic
-
-static void
-my_clear_vm_thread_ptr_safe(JNIEnv *jenv, jobject jThreadObj)
-{
- assert(tmn_is_suspend_enabled());
- jclass jThreadClass = jenv->GetObjectClass(jThreadObj);
- jfieldID field_id = jenv->GetFieldID(jThreadClass, "vm_thread", "J");
- jenv->SetLongField(jThreadObj, field_id, (jlong) NULL);
- assert(tmn_is_suspend_enabled());
-} //my_clear_vm_thread_ptr_safe
-
-// This method should be called when Thread.run() execution ended with an exception.
-static void process_uncaught_exception(VM_thread *p_vm_thread, ManagedObject *exn) {
- // create handle for exception object
- ObjectHandle exn_handle = oh_allocate_local_handle();
- exn_handle->object = exn;
-
- // create handle for java.lang.Thread object
- ObjectHandle thread_handle = oh_allocate_local_handle();
- thread_handle->object = (ManagedObject*) p_vm_thread->p_java_lang_thread;
-
- // lookup Thread.getThreadGroup() method
- String *name = VM_Global_State::loader_env->string_pool.lookup("getThreadGroup");
- String *descr = VM_Global_State::loader_env->string_pool.lookup("()Ljava/lang/ThreadGroup;");
-
- VTable *p_vtable = (((ManagedObject *)thread_handle->object)->vt());
- Method *getThreadGroup_method = class_lookup_method_recursive(p_vtable->clss, name, descr);
- assert(getThreadGroup_method);
-
- // execute Thread.getThreadGroup() method in order to get threadGroup
- jvalue getThreadGroup_args[1];
- jvalue threadGroup;
- //tmn_suspend_enable();
- getThreadGroup_args[0].l = (jobject) thread_handle; // this
- vm_execute_java_method_array((jmethodID) getThreadGroup_method, &threadGroup, getThreadGroup_args);
- //tmn_suspend_disable();
-
- // check for exception
- ManagedObject* cte = get_current_thread_exception();
- clear_current_thread_exception();
- if (cte || ! threadGroup.l) {
- print_uncaught_exception_message(stderr, "thread execution", exn_handle->object);
- return;
- }
-
- // lookup ThreadGroup.uncaughtException() method
- name = VM_Global_State::loader_env->string_pool.lookup("uncaughtException");
- descr = VM_Global_State::loader_env->string_pool.lookup("(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
-
- p_vtable = (((ManagedObject *)threadGroup.l->object)->vt());
- Method *uncaughtException_method = class_lookup_method_recursive(p_vtable->clss, name, descr);
- assert(uncaughtException_method);
-
- // execute ThreadGroup.uncaughtException() method
- jvalue uncaughtException_args[3];
- //tmn_suspend_enable();
- uncaughtException_args[0].l = (jobject) threadGroup.l; // this
- uncaughtException_args[1].l = (jobject) thread_handle; // Thread
- uncaughtException_args[2].l = (jobject) exn_handle; // Throwable
- vm_execute_java_method_array((jmethodID) uncaughtException_method, NULL, uncaughtException_args);
- //tmn_suspend_disable();
-
- // check for exception
- cte = get_current_thread_exception();
- clear_current_thread_exception();
- if (cte) {
- print_uncaught_exception_message(stderr, "thread execution", exn_handle->object);
- return;
+IDATA vm_attach() {
+ //hythread_suspend_disable();
+ IDATA status;
+ status = hythread_global_lock();
+ if(status != TM_ERROR_NONE)
+ return status;
+ VM_thread * p_vm_thread = get_a_thread_block();
+ if (NULL == p_vm_thread) {
+ TRACE2("thread", "can't get a thread block for a new thread");
+ status =hythread_global_unlock();
+ assert (status == TM_ERROR_NONE);
+ return TM_ERROR_OUT_OF_MEMORY;
}
-}
-
-//JNI implementation
-void __cdecl call_the_run_method( void * p_args )
-{
-#ifdef _IA32_
- init_stack_info();
-#ifdef PLATFORM_POSIX
- set_guard_stack();
-#endif // PLATFORM_POSIX
-#endif // _IA32_
-
- //when a new thread created, gc is disabled, because VM thread structure
- //was set 0 initially, then gc_enabled_status kept 0 till now
- VM_thread *p_vm_thread=(VM_thread *)(((void **)p_args)[0]);
- JNIEnv *jenv=(JNIEnv *)(((void **)p_args)[1]);
- ObjectHandle jThreadSelf = ((ObjectHandle*)p_args)[2];
-
- jvmtiEnv * jvmti_Env = (jvmtiEnv *)((void **)p_args)[3];
- jvmtiStartFunction jvmtiStartProc = (jvmtiStartFunction)((void **)p_args)[4];
- void* jvmtiStartProcArg = ((void **)p_args)[5];
set_TLS_data(p_vm_thread);
- MARK_STACK_END
-
- tmn_suspend_disable();
-
- m2n_set_last_frame(NULL);
-
- p_vm_thread->thread_id = GetCurrentThreadId();
-
- // Invoke Thread.run()
- // BUGBUG its an interface method but we cheat by looking up "run" in the instance instead of going thru interface lookup
- String *name = VM_Global_State::loader_env->string_pool.lookup("run");
- String *descr = VM_Global_State::loader_env->string_pool.lookup("()V");
-
- VTable *p_vtable = (((ManagedObject *)p_vm_thread->p_java_lang_thread)->vt());
- Method *start_method = class_lookup_method_recursive(p_vtable->clss, name, descr);
- assert(start_method);
-
- SET_THREAD_DATA_MACRO();
-
- int old_floating_point_state = 0;
- void setup_floating_point_state(int *);
- setup_floating_point_state(&old_floating_point_state);
- // Set the app_status to "running" just before entering Java code. It is "birthing" till now.
+ M2nFrame* p_m2n = (M2nFrame*) STD_MALLOC(sizeof(M2nFrame));
+ ObjectHandles* p_handles = (ObjectHandles*) STD_MALLOC (sizeof(ObjectHandlesNew));
+ if ((p_m2n==NULL)||(p_handles==NULL))
+ {
+ TRACE2("thread", "can't get a thread block for a new thread");
+ status =hythread_global_unlock();
+ assert (status == TM_ERROR_NONE);
+ return TM_ERROR_OUT_OF_MEMORY;
+ }
+ status =hythread_global_unlock();
+ if(status != TM_ERROR_NONE)
+ return status;
- p_vm_thread->app_status = thread_is_running;
- active_thread_count ++;
+ hythread_suspend_disable();
- // the thread that originally called java_lang_Thread_start() will wait for this event
- jint UNUSED stat = vm_set_event(new_thread_started_handle);
- assert(stat);
+ m2n_null_init(p_m2n);
+ m2n_set_last_frame(p_m2n);
- // The scope of lhs must be very precise to make it work properly
- { NativeObjectHandles lhs;
+ oh_null_init_handles(p_handles);
+ m2n_set_local_handles(p_m2n, p_handles);
+ m2n_set_frame_type(p_m2n, FRAME_NON_UNWINDABLE);
gc_thread_init(&p_vm_thread->_gc_private_information);
- assert(!tmn_is_suspend_enabled());
- tmn_suspend_enable();
- jvmti_send_thread_start_end_event(1);
- tmn_suspend_disable();
-
- jvalue args[1];
- ObjectHandle h = oh_allocate_local_handle();
- h->object = (ManagedObject*) p_vm_thread->p_java_lang_thread;
- args[0].l = (jobject) h;
-
- if (jvmtiStartProc){
- // ppervov: all JVM TI agent functions must be run with gc enabled
- tmn_suspend_enable();
- jvmtiStartProc(jvmti_Env, jenv, jvmtiStartProcArg);
- tmn_suspend_disable();
- } else {
- //tmn_suspend_enable();
-
- vm_execute_java_method_array((jmethodID) start_method, 0, args);
- //tmn_suspend_disable();
+ assert(!hythread_is_suspend_enabled());
+ hythread_suspend_enable();
+ return TM_ERROR_NONE;
}
- assert(!tmn_is_suspend_enabled());
-
- // If an exception resulted from calling the run method, call
- // ThreadGroup.uncaughtException()
- ManagedObject* exn = get_current_thread_exception();
- clear_current_thread_exception();
- if (exn)
- process_uncaught_exception(p_vm_thread, exn);
-
- void cleanup_floating_point_state(int);
- cleanup_floating_point_state(old_floating_point_state);
-
- clear_current_thread_exception();
- tmn_suspend_enable();
- jvmti_send_thread_start_end_event(0);
- tmn_suspend_disable();
-
- assert(p_vm_thread->app_status == thread_is_running);
-
- Method *kill_method = class_lookup_method_recursive(p_vtable->clss, "kill", "()V");
- assert(kill_method);
- vm_execute_java_method_array((jmethodID) kill_method, 0, args);
- assert(!exn_raised());
-
- p_vm_thread->app_status = thread_is_dying;
+IDATA vm_detach() {
+ IDATA status;
+ VM_thread *p_vm_thread=get_thread_ptr();
+ hythread_suspend_disable();
+// assert(p_vm_thread->app_status == thread_is_running);
gc_thread_kill(&p_vm_thread->_gc_private_information);
-
- tmn_suspend_enable();
- vm_monitor_enter_slow_handle(jThreadSelf);
-
- thread_object_notify_all(jThreadSelf);
- vm_monitor_exit_handle(jThreadSelf);
-
- tm_acquire_tm_lock();
-
- if (! is_daemon_thread(jenv, (jobject)jThreadSelf)) {
- non_daemon_thread_count--;
- TRACE2("thread", "non daemon threads removed: " << non_daemon_thread_count);
+ hythread_suspend_enable();
- }
- //--------------------------------------------------------- fix 979
- // pointer to VM_thread structure wasn't cleared and was
- // wrongly used after correasponding thread was terminated and
- // VM_thread structure was reused for another thread
- my_clear_vm_thread_ptr_safe(jenv, (jobject)jThreadSelf);
- //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ fix 979
- } // end of scope for lhs
-
- // We should remove those useless global handles
- oh_deallocate_global_handle(jThreadSelf);
- tmn_suspend_disable();
-
- /*
- wgs: I did meet with the assertion failure here. The scenario is:
- A Thread.run() begins to compile a method, but fails in loading
- some exception classes which are necessary for compiling the method,
- thus ClassNotFoundException is throwed. Thread.run() has a handler
- for all exception, so it catches and exits, but note that the compilation
- of the method never finishes.
- That might prevent further compilation because we have global compile lock.
-
- Should we use a defensive way:
- if (p_vm_thread->gc_frames != 0)
- p_jit_a_method_lock->_unlock();
- */
+ status = hythread_global_lock();
+ if(status != TM_ERROR_NONE)
+ return status;
assert(p_vm_thread->gc_frames == 0);
free_this_thread_block( p_vm_thread );
set_TLS_data(NULL);
- THREAD_CLEANUP();
-
- TRACE2("thread", "non daemon threads count: " << non_daemon_thread_count);
- if (!non_daemon_thread_count) {
- TRACE2("thread", "non_daemon_threads_dead_handle set" );
- jint UNUSED stat = vm_set_event(non_daemon_threads_dead_handle);
- assert(stat);
+ status =hythread_global_unlock();
+ return status;
}
-
- active_thread_count --;
- tm_release_tm_lock();
- vm_endthread();
-}
-
-
-void thread_start(JNIEnv* jenv, jobject jthread)
-{
- Java_java_lang_Thread_start_generic(jenv, jthread, NULL, NULL, NULL, 5);
-} //thread_start
-
-//JNI implementation
-void Java_java_lang_Thread_start_generic(JNIEnv *jenv, jobject jThreadSelf,
- jvmtiEnv * jvmtiEnv, jvmtiStartFunction proc,
- const void* arg, jint priority)
-{
- //GC is enabled in JNI invocation of Java_java_lang_Thread_start
-
- // get a nursery for child thread. this invocation previously is
- // by child thread itself in call_the_run_method()
-
- //BUGBUG this should throw IllegalThreadStateException
- // because field in use means thread is already running
- assert(! get_vm_thread_ptr_safe(jenv, jThreadSelf));
-
- tm_acquire_tm_lock();
- TRACE2("thread", "starting a new thread");
-
- VM_thread * p_vm_thread = get_a_thread_block();
- if (NULL == p_vm_thread) {
- tm_release_tm_lock();
- TRACE2("thread", "can't get a thread block for a new thread");
- exn_raise_by_name("java/lang/OutOfMemoryError",
- "too many threads created");
- return;
- }
-
- p_vm_thread->p_java_lang_thread = ((ObjectHandle)jThreadSelf)->object;
-
- set_vm_thread_ptr_safe(jenv, jThreadSelf, (jlong) POINTER_SIZE_INT(p_vm_thread));
-
- assert(get_vm_thread_ptr_safe(jenv, jThreadSelf));
-
- if (! is_daemon_thread(jenv, (jobject)jThreadSelf)) {
- non_daemon_thread_count++;
- TRACE2("thread", "non daemon threads total: " << non_daemon_thread_count);
- }
- ObjectHandle hThreadSelf = oh_allocate_global_handle();
- tmn_suspend_disable();
- hThreadSelf->object = ((ObjectHandle)jThreadSelf)->object;
-
- void *p_args[7]={(void*)p_vm_thread, (void*)jenv, (void *)hThreadSelf,
- (void*)jvmtiEnv, (void*)proc, (void*)arg, (void*)((POINTER_SIZE_INT)priority)};
-
-
-VmThreadHandle stat = vm_beginthread(
- (void(__cdecl *)(void *))call_the_run_method2,
- (unsigned)(64*1024),
- (void *)p_args);
-
- if (!stat) {
- TRACE2("thread", "thread failed to start, raising OOME");
- free_this_thread_block(p_vm_thread);
- tmn_suspend_enable();
- set_vm_thread_ptr_safe(jenv, jThreadSelf, (jlong) 0);
- assert(get_vm_thread_ptr_safe(jenv, jThreadSelf) == NULL);
- tm_release_tm_lock();
- exn_raise_by_name("java/lang/OutOfMemoryError",
- "can't start new thread");
- return;
- }
-
- p_vm_thread->thread_handle = stat;
-
- Sleep(0);
-
- // the new thread just resumed above will set new_thread_started_handle
- int status;
- //FIXME we should release thread_Lock before wait.
- status = vm_wait_for_single_object(new_thread_started_handle, INFINITE);
-
- ASSERT(status != (int)WAIT_FAILED, "Unexpected error while starting new thread: " << IJGetLastError());
-
- tmn_suspend_enable();
- assert(thread_is_birthing != p_vm_thread->app_status);
- tm_release_tm_lock();
-} //Java_java_lang_Thread_start_generic
-
-
-//
-// For IPF configuration this method is defined in nt_exception_filter.cpp
-//
-
-#if !defined(_IPF_) || defined(PLATFORM_POSIX)
-#ifdef __INTEL_COMPILER
-#pragma optimize("", off)
-#endif
-void __cdecl call_the_run_method2(void *p_args)
-{
- VM_thread *p_vm_thread;
- p_vm_thread = (VM_thread *)(((void **)p_args)[0]);
-
- set_TLS_data(p_vm_thread);
-
- // Hyperthreading (HT) optimization. We allocate extra space on the stack
- // so that each thread's stack is "misaligned" with other threads' stacks.
- // The offset is 256*thead_index, capped at 16KB.
- if (VM_Global_State::loader_env->is_hyperthreading_enabled)
- {
- STD_ALLOCA(((p_TLS_vmthread->thread_index - 1) % 64) * 256);
- }
-
-#ifdef PLATFORM_POSIX
- call_the_run_method( p_args );
-#else // !PLATFORM_POSIX
-
- // A temporary patch needed to support j9 class libraries.
- // TODO: remove it after the needed subset of j9thread functions is implemented.
-
- {
- static HINSTANCE hDLL; // Handle to j9thr23.dll
- typedef void* (*lpFunc)(void*); //
- static lpFunc func; // j9thread_attach proc address
- static boolean firstAttempt = true;
-
- if (firstAttempt) {
- hDLL = GetModuleHandle("j9thr23.dll");
- // hDLL = LoadLibrary("j9thr23");
-
- if (hDLL != NULL) {
- func = (lpFunc)GetProcAddress(hDLL, "j9thread_attach");
- }
- }
-
- if (func != NULL) {
- func(NULL); // Attach to j9thread
- }
- }
-
- call_the_run_method( p_args );
-#endif //#ifdef PLATFORM_POSIX
-
-}
-#ifdef __INTEL_COMPILER
-#pragma optimize("", on)
-#endif
-#endif // !_IPF_
-
-
////////////////////////////////////////////////////////////////////////////////////////////
//////// CALLED by vm_init() to initialialize thread groups and create the main thread ////
-////////////////////////////////////////////////////////////////////////////////////////////
-
-
-bool init_threadgroup()
-{
- NativeObjectHandles lhs; // allows us to create handles in native code not called from JITed code
-
- Global_Env *env = VM_Global_State::loader_env;
- JNIEnv *jenv = (JNIEnv *)jni_native_intf;
-
- assert(tmn_is_suspend_enabled());
-
- // Load, prepare and initialize the "Thread class"
- String *ss = env->string_pool.lookup("java/lang/Thread");
- Class *thread_clss = env->bootstrap_class_loader->LoadVerifyAndPrepareClass(env, ss);
- assert(tmn_is_suspend_enabled());
- tmn_suspend_disable();
- class_initialize(thread_clss);
- assert(!tmn_is_suspend_enabled());
-
- ObjectHandle jThreadClass = oh_allocate_local_handle();
- ObjectHandle jname = oh_allocate_local_handle();
- ObjectHandle jMainThreadObj = oh_allocate_local_handle();
- jThreadClass->object = struct_Class_to_java_lang_Class(thread_clss);
- jname->object = string_create_from_utf8("init", 4);
-
- // Allocate the Thread object for ... public static void main(String args[])
- // Volatile needed here since GC is enabled by JNI functions below and the use of
- // "main_thread_obj" after the JNI calls shouldnt become stale.
- volatile ManagedObject *main_thread_obj = class_alloc_new_object(thread_clss);
- assert(main_thread_obj);
-
- jMainThreadObj->object = (ManagedObject *) main_thread_obj;
-
- p_TLS_vmthread->thread_id = GetCurrentThreadId();
- p_TLS_vmthread->p_java_lang_thread = jMainThreadObj->object;
- tmn_suspend_enable();
- assert(tmn_is_suspend_enabled());
-
- // Set all all attributes for "main" thread
- set_vm_thread_ptr_safe(jenv, (jobject)jMainThreadObj, (jlong) POINTER_SIZE_INT(p_TLS_vmthread));
-
- // Call constructor for java.lang.Thread object of "main" thread
- if (! init_thread_object(jenv, (jobject) jMainThreadObj))
- return false;
-
- int UNUSED stat =
- DuplicateHandle(GetCurrentProcess(), // handle to process with handle to duplicate
- GetCurrentThread(), // handle to duplicate
- GetCurrentProcess(), // handle to process to duplicate to
- // gashiman - Duplicate handle does not do anything on linux
- // so it is safe to put type convertion here
- (VmEventHandle*)&(p_TLS_vmthread->thread_handle), // pointer to duplicate handle
- 0, // access for duplicate handle
- false, // handle inheritance flag
- DUPLICATE_SAME_ACCESS // optional actions
- );
- assert(stat);
-
- p_TLS_vmthread->thread_id = GetCurrentThreadId();
-
-#ifdef PLATFORM_POSIX
-#else
- assert(p_TLS_vmthread->event_handle_monitor);
-#endif
-
- return true;
-} //init_threadgroup
-
-// Alexei
-// migrating to C interfaces for Linux
-#if (defined __cplusplus) && (defined PLATFORM_POSIX)
-extern "C" {
-#endif
-
-jobject thread_current_thread()
-{
- void *thread_ptr = get_thread_ptr();
- tmn_suspend_disable(); //------------v-----------
- ObjectHandle hThread = NULL;
- ManagedObject* object = (struct ManagedObject *)((VM_thread*)thread_ptr)->p_java_lang_thread;
- if (object)
- {
- hThread = oh_allocate_local_handle();
- hThread->object = object;
- }
- tmn_suspend_enable(); //------------^-----------
- return (jobject)hThread;
-} //thread_current_thread
-
-bool thread_is_alive(jthread thread)
-{
- VM_thread *p_vmthread = my_get_vm_thread_ptr_safe(jni_native_intf, thread);
- if ( !p_vmthread ) {
- return 0; // don't try to isAlive() non-existant thread
- }
-
- java_state as = p_vmthread->app_status;
-
- // According to JAVA spec, this method should return true, if and
- // only if the thread has been started and not yet died.
- switch (as) {
- case thread_is_sleeping:
- case thread_is_waiting:
- case thread_is_timed_waiting:
- case thread_is_blocked:
- case thread_is_running:
- case thread_is_birthing:
- return 1;
- //break; // exclude remark #111: statement is unreachable
- case thread_is_dying:
- case zip:
- return 0;
- //break; // exclude remark #111: statement is unreachable
- default:
- DIE("big problem in java_lang_Thread_isAlive(), p_vmthread->appstatus == " << ((int)as));
- return 0;
- //break; // exclude remark #111: statement is unreachable
- }
- // must return from inside the switch statement // remark #111: statement is unreachable
-} //thread_is_alive
-
-void thread_suspend(jobject jthread)
-{
- tm_acquire_tm_lock();
- // if thread is not alived do nothing
- if(!thread_is_alive(jthread)) {
- tm_release_tm_lock();
- return;
- }
- VM_thread * vm_thread = get_vm_thread_ptr_safe(jni_native_intf, jthread);
- thread_suspend_generic(vm_thread);
- tm_release_tm_lock();
-}
-
-void thread_resume(jobject jthread)
-{
- tm_acquire_tm_lock();
- // if thread is not alived do nothing
- if(!thread_is_alive(jthread)) {
- tm_release_tm_lock();
- return;
- }
- VM_thread * vm_thread = get_vm_thread_ptr_safe(jni_native_intf, jthread);
- thread_resume_generic(vm_thread);
- tm_release_tm_lock();
-}
-
-void thread_join(jthread thread, long millis, int UNREF nanos)
-{
- assert(thread);
- VM_thread* self = get_thread_ptr();
-
- vm_monitor_enter_slow_handle(thread);
- while (thread_is_alive(thread)
- && WAIT_TIMEOUT != java_lang_Object_wait(thread, millis)
- && false == self->interrupt_a_waiting_thread ) {
- // propogate not our notify
- // in any case spurious notify allowed by spec
- thread_object_notify(thread);
- }
- vm_monitor_exit_handle(thread);
-} //thread_join
-
-void thread_interrupt(jobject jthread)
-{
- VM_thread *p_vmthread = my_get_vm_thread_ptr_safe(jni_native_intf, jthread);
- //XXX this is a temporary solution
- // the upcoming threading design should eliminate the cases no object
- // representing a thread exists
- if (p_vmthread) {
- Java_java_lang_Thread_interrupt_generic(p_vmthread);
- }
-}
-
-bool thread_is_interrupted(jobject thread, bool clear)
-{
- VM_thread *p_thr = my_get_vm_thread_ptr_safe(jni_native_intf, thread);
- //XXX this is a temporary solution
- // the upcoming threading design should eliminate the cases no object
- // representing a thread exists
- if (p_thr){
- jboolean res = (jboolean)(p_thr->interrupt_a_waiting_thread ? TRUE : FALSE);
- if (clear) p_thr->interrupt_a_waiting_thread = false;
- return res;
- }
- return FALSE;
-}
-
-void* thread_get_interrupt_event()
-{
- VM_thread* thr = get_thread_ptr();
- return (void*)thr->event_handle_notify_or_interrupt;
-}
-
-#if (defined __cplusplus) && (defined PLATFORM_POSIX)
-}
-#endif
-
-int parktimed(jlong milis, jint nanos) {
- assert(tmn_is_suspend_enabled());
- int ret_val;
- if (milis<=0 && nanos <=0) return 0;
-
- ret_val = WaitForSingleObject(p_TLS_vmthread->park_event,(DWORD)milis);
-
- return ret_val;
-}
-
-int parkuntil(jlong milis, jint UNREF nanos) {
- assert(tmn_is_suspend_enabled());
- int ret_val;
- jlong delta = milis - get_current_time();
- if (delta <= 0) return 0;
-
- ret_val = WaitForSingleObject(p_TLS_vmthread->park_event, (DWORD)delta);
-
- return ret_val;
-}
-
-int park(void) {
- assert(tmn_is_suspend_enabled());
- int ret_val;
- ret_val = WaitForSingleObject(p_TLS_vmthread->park_event, INFINITE);
-
- return ret_val;
-}
-
-int unpark(VM_thread *thread) {
- return SetEvent(thread->park_event);
-}
-
-void wait_until_non_daemon_threads_are_dead() {
- tm_acquire_tm_lock();
-
- if(!non_daemon_thread_count) {
- tm_release_tm_lock();
- return;
- }
- tm_release_tm_lock();
-
- // the following lines allow MSVC++ "Debug->>>Break" to work
- while (1) {
- DWORD stat = vm_wait_for_single_object(non_daemon_threads_dead_handle, 2000);
- if (stat == WAIT_OBJECT_0) {
- INFO("VM is signalled to shutdown");
- break;
- }
- assert(stat != WAIT_FAILED);
-
- }
-
-} //wait_until_non_daemon_threads_are_dead
-
-void terminate_all_threads() {
- tm_iterator_t * iterator = tm_iterator_create();
- VM_thread *self = p_TLS_vmthread;
- volatile VM_thread *p_scan = tm_iterator_next(iterator);
- while (p_scan) {
- if(p_scan != self) {
- vm_terminate_thread (p_scan->thread_handle);
- }
- p_scan = tm_iterator_next(iterator);
- }
- tm_iterator_release(iterator);
-}
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_manager.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_manager.cpp?rev=434076&r1=434075&r2=434076&view=diff
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_manager.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_manager.cpp Wed Aug 23 09:48:41 2006
@@ -19,6 +19,8 @@
*/
+#include "open/thread_externals.h"
+
#include "platform_lowlevel.h"
#include <assert.h>
@@ -31,6 +33,14 @@
#include "vm_process.h"
#endif
+#include "object_layout.h"
+#include "open/vm_util.h"
+#include "object_handles.h"
+//FIXME remove this code
+#include "exceptions.h"
+#include "Class.h"
+#include "environment.h"
+
#include "open/vm_util.h"
#include "nogc.h"
#include "sync_bits.h"
@@ -39,6 +49,9 @@
#include "lock_manager.h"
#include "thread_manager.h"
#include "thread_generic.h"
+#include "open/thread_helpers.h"
+#include "open/jthread.h"
+
#include "vm_threads.h"
#define LOG_DOMAIN "thread"
#include "cxxlog.h"
@@ -61,22 +74,7 @@
static tl::MemoryPool thr_pool;
-VM_thread *p_threads_iterator;
-VM_thread *p_free_thread_blocks;
-VM_thread *p_active_threads_list;
-
-#ifdef USE_TLS_API
-#ifdef PLATFORM_POSIX
-__thread VM_thread *p_TLS_vmthread = NULL;
-VM_thread *get_thread_ptr()
-{
- return p_TLS_vmthread;
-}
-
-#else //PLATFORM_POSIX
-__declspec( thread ) VM_thread *p_TLS_vmthread;
-#endif //PLATFORM_POSIX else
-#endif //USE_TLS_API
+hythread_tls_key_t TLS_key_pvmthread;
#ifdef __cplusplus
extern "C" {
@@ -84,38 +82,16 @@
volatile VM_thread *p_the_safepoint_control_thread = 0; // only set when a gc is happening
volatile safepoint_state global_safepoint_status = nill;
-// Incremented at the start and at the end of each GC. The total number
-// of GC is this number * 2. This is done so that when a lot of application
-// threads discover that they need a GC only on is done.
-
-unsigned non_daemon_thread_count = 0;
-
-VmEventHandle non_daemon_threads_dead_handle = 0;
-VmEventHandle new_thread_started_handle = 0;
-
-VmEventHandle non_daemon_threads_are_all_dead;
-
-thread_array quick_thread_id[MAX_VM_THREADS];
-POINTER_SIZE_INT hint_free_quick_thread_id;
#ifdef __cplusplus
}
#endif
-#ifdef _DEBUG
-////////////Object_Handle vm_create_global_object_handle(); // bugbug -- where does this go?
-#include "jni.h"
-#endif
-
+void init_TLS_data();
void vm_thread_init(Global_Env * UNREF p_env___not_used)
{
- new_thread_started_handle = vm_create_event(
- NULL, // pointer to security attributes
- FALSE, // flag for manual-reset event -- auto reset mode
- FALSE, // flag for initial state
- N_T_S_H // pointer to event-object name
- );
+ init_TLS_data();
}
@@ -128,323 +104,118 @@
VM_thread * get_a_thread_block()
{
VM_thread *p_vmthread;
- int thread_index;
- for( thread_index=1; thread_index < MAX_VM_THREADS; thread_index++ ){
- if (quick_thread_id[thread_index].p_vmthread == NULL )
- break;
+ p_vmthread = p_TLS_vmthread;
+ if (!p_vmthread) {
+ p_vmthread = (VM_thread *)thr_pool.alloc(sizeof(VM_thread));
+ memset(p_vmthread, 0, sizeof(VM_thread) );
}
- if (thread_index == MAX_VM_THREADS){
- WARN("Out of java threads, maximum is " << MAX_VM_THREADS);
- return NULL;
+ return p_vmthread;
}
- next_thread_index = (thread_index == next_thread_index)? ++next_thread_index : next_thread_index;
-
- if (p_free_thread_blocks) {
- p_vmthread = p_free_thread_blocks;
- p_free_thread_blocks = p_free_thread_blocks->p_free;
- p_vmthread->p_free = 0;
- p_vmthread->app_status = thread_is_birthing;
- TRACE2("thread", "Reusing old thread block " << p_vmthread << " for a new thread");
+void free_this_thread_block(VM_thread *p_vmthread)
+{
}
- else {
- p_vmthread = (VM_thread *)thr_pool.alloc(sizeof(VM_thread));
- memset(p_vmthread, 0, sizeof(VM_thread) );
- TRACE2("thread", "Creating new thread block " << p_vmthread);
- //park semaphore initialization
- p_vmthread->park_event = CreateEvent(
- NULL, // pointer to security attributes
- FALSE, // flag for manual-reset event -- auto reset mode
- FALSE, // flag for initial state
- NULL // pointer to event-object name
- );
-
- // If new thread block is being created, set app_status to "birthing" here too.
- p_vmthread->app_status = thread_is_birthing;
-
- p_vmthread->event_handle_monitor = vm_create_event(
- NULL, // pointer to security attributes
- FALSE, // flag for manual-reset event -- auto reset mode
- FALSE, // flag for initial state
- E_H_M // pointer to event-object name
- );
- assert(p_vmthread->event_handle_monitor);
-
- p_vmthread->event_handle_sleep = vm_create_event(
- NULL, // pointer to security attributes
- FALSE, // flag for manual-reset event -- auto reset mode
- FALSE, // flag for initial state
- E_H_S // pointer to event-object name
- );
- assert(p_vmthread->event_handle_sleep);
-
- p_vmthread->event_handle_notify_or_interrupt = vm_create_event(
- NULL, // pointer to security attributes
- FALSE, // flag for manual-reset event -- auto reset mode
- FALSE, // flag for initial state
- E_H_I // pointer to event-object name
- );
- assert(p_vmthread->event_handle_notify_or_interrupt);
-
- p_vmthread->jvmti_resume_event_handle = vm_create_event(
- NULL, // pointer to security attributes
- TRUE, // flag for manual-reset event -- manual mode
- TRUE, // flag for initial state
- J_V_M_T_I_E_H // pointer to event-object name
- );
- assert(p_vmthread->jvmti_resume_event_handle);
-
- // ============== new SUSPEND related variables setup =====================
- p_vmthread->suspend_request = 0;
- p_vmthread->suspended_event = vm_create_event(
- NULL, // pointer to security attributes
- TRUE, // flag for manual-reset event -- manual mode
- FALSE, // flag for initial state
- E_H_S0 // pointer to event-object name
- ); // set when thread is suspended
-
- assert(p_vmthread->suspended_event);
-
- p_vmthread->resume_event = vm_create_event(
- NULL, // pointer to security attributes
- FALSE, // flag for manual-reset event -- manual mode
- TRUE, // flag for initial state
- NULL // pointer to event-object name
- ); // set when thread is suspended
- assert(p_vmthread->resume_event);
+void vm_thread_attach()
+{
+ VM_thread *p_vmthread;
+ p_vmthread = p_TLS_vmthread;
+ if (!p_vmthread) {
+ p_vmthread = (VM_thread *)thr_pool.alloc(sizeof(VM_thread));
+ memset(p_vmthread, 0, sizeof(VM_thread) );
+ set_TLS_data(p_vmthread);
}
-#ifdef PLATFORM_POSIX
- sem_init(&p_vmthread->yield_other_sem,0,0);
-#endif
- p_vmthread->p_active = p_active_threads_list;
- p_active_threads_list = p_vmthread;
- p_vmthread->thread_index = thread_index;
- quick_thread_id[thread_index].p_vmthread = p_vmthread;
- mon_enter_array[thread_index].p_thr = p_vmthread;
- mon_wait_array[thread_index].p_thr = p_vmthread;
- p_vmthread->native_handles = 0;
+} //init_thread_block
- return p_vmthread;
+VM_thread *get_vm_thread(hythread_t thr) {
+ if (thr == NULL) {
+ return NULL;
}
-
-#ifdef RECOMP_THREAD
-VM_thread* new_a_thread_block()
-{ //::
- VM_thread* p_vmthread = (VM_thread *)thr_pool.alloc(sizeof(VM_thread));
- TRACE2("thread", "new_a_thread_block() created new thread block " << p_vmthread);
- memset(p_vmthread, 0, sizeof(VM_thread) );
-
- p_vmthread->park_event = CreateEvent(
- NULL, // pointer to security attributes
- FALSE, // flag for manual-reset event -- auto reset mode
- FALSE, // flag for initial state
- NULL // pointer to event-object name
- );
-
- // If new thread block is being created, set app_status to "birthing" here too.
- p_vmthread->app_status = thread_is_birthing;
-
- p_vmthread->event_handle_monitor = vm_create_event(
- NULL, // pointer to security attributes
- FALSE, // flag for manual-reset event -- auto reset mode
- FALSE, // flag for initial state
- E_H_M // pointer to event-object name
- );
- assert(p_vmthread->event_handle_monitor);
-
- p_vmthread->event_handle_sleep = vm_create_event(
- NULL, // pointer to security attributes
- FALSE, // flag for manual-reset event -- auto reset mode
- FALSE, // flag for initial state
- E_H_S // pointer to event-object name
- );
- assert(p_vmthread->event_handle_sleep);
-
- p_vmthread->event_handle_notify_or_interrupt = vm_create_event(
- NULL, // pointer to security attributes
- FALSE, // flag for manual-reset event -- auto reset mode
- FALSE, // flag for initial state
- E_H_I // pointer to event-object name
- );
- assert(p_vmthread->event_handle_notify_or_interrupt);
-
- p_vmthread->jvmti_resume_event_handle = vm_create_event(
- NULL, // pointer to security attributes
- TRUE, // flag for manual-reset event -- manual mode
- TRUE, // flag for initial state
- J_V_M_T_I_E_H // pointer to event-object name
- );
- assert(p_vmthread->jvmti_resume_event_handle);
-
- //park semaphore initialization
-
- // ============== new SUSPEND related variables setup =====================
- p_vmthread->suspend_request = 0;
- p_vmthread->suspended_event = vm_create_event(
- NULL, // pointer to security attributes
- TRUE, // flag for manual-reset event -- manual mode
- FALSE, // flag for initial state
- E_H_S0 // pointer to event-object name
- ); // set when thread is suspended
-
- assert(p_vmthread->suspended_event);
-
- p_vmthread->resume_event = vm_create_event(
- NULL, // pointer to security attributes
- FALSE, // flag for manual-reset event -- manual mode
- TRUE, // flag for initial state
- NULL // pointer to event-object name
- ); // set when thread is suspended
- assert(p_vmthread->resume_event);
-#ifdef PLATFORM_POSIX
- sem_init(&p_vmthread->yield_other_sem,0,0);
-#endif
- return p_vmthread;
+ return (VM_thread *)hythread_tls_get(thr, TLS_key_pvmthread);
}
-#endif
-void free_this_thread_block(VM_thread *p_vmthread)
+VM_thread *get_vm_thread_ptr_safe(JNIEnv *jenv, jobject jThreadObj)
{
- assert(quick_thread_id[p_vmthread->thread_index].p_vmthread == p_vmthread);
-
- VM_thread *p_thr = p_active_threads_list;
- VM_thread *p_old_thr = p_active_threads_list;
+ hythread_t t=jthread_get_native_thread(jThreadObj);
+ if(t == NULL) {
+ return NULL;
+ }
+ return (VM_thread *)hythread_tls_get(t, TLS_key_pvmthread);
+}
- // pull thread out of active threads list
- if (p_thr == p_vmthread)
- p_active_threads_list = p_thr->p_active;
-
- else {
- while (1) {
- if(p_thr == p_vmthread) break;
- p_old_thr = p_thr;
- p_thr = p_thr->p_active;
- }
- assert(p_thr);
- assert(p_old_thr);
- p_old_thr->p_active = p_thr->p_active;
- }
+VM_thread *get_thread_ptr_stub()
+{
- // put it back in the free threads pool
- quick_thread_id[p_vmthread->thread_index].p_vmthread = 0;
- mon_enter_array[p_vmthread->thread_index].p_thr = NULL;
- mon_wait_array[p_vmthread->thread_index].p_thr = NULL;
-
- // copy the handles into a temporary place
- // and put them back after zeroing whole data struct
- VmEventHandle aa = p_vmthread->event_handle_monitor;
- VmEventHandle bb = p_vmthread->event_handle_sleep;
- VmEventHandle cc = p_vmthread->event_handle_notify_or_interrupt;
- VmEventHandle ff = p_vmthread->jvmti_resume_event_handle;
- VmEventHandle jj = p_vmthread->suspended_event;
- VmEventHandle hh = p_vmthread->resume_event;
- VmEventHandle gg = p_vmthread->park_event;
- #ifdef PLATFORM_POSIX
- sem_destroy(&p_vmthread->yield_other_sem);
-#endif
+ return NULL;
+}
- memset(p_vmthread, 0, sizeof(VM_thread) );
+vm_thread_accessor* get_thread_ptr = get_thread_ptr_stub;
+void init_TLS_data() {
+ hythread_tls_alloc(&TLS_key_pvmthread);
+ get_thread_ptr = (vm_thread_accessor*) get_tls_helper(TLS_key_pvmthread);
+ //printf ("init fast call %p\n", get_thread_ptr);
+}
- vm_reset_event(gg);
- p_vmthread->park_event = gg;
-
- vm_reset_event(aa);
- p_vmthread->event_handle_monitor = aa;
- vm_reset_event(bb);
- p_vmthread->event_handle_sleep = bb;
- vm_reset_event(cc);
- p_vmthread->event_handle_notify_or_interrupt = cc;
- vm_reset_event(ff);
- vm_set_event(ff);
- p_vmthread->jvmti_resume_event_handle = ff;
- vm_reset_event(jj);
- p_vmthread->suspended_event = jj;
- vm_reset_event(hh);
- vm_set_event(hh);
- p_vmthread->resume_event = hh;
-
-#ifdef PLATFORM_POSIX
- sem_init(&p_vmthread->yield_other_sem,0,0);
-#endif
-
- p_vmthread->p_free = p_free_thread_blocks;
- p_free_thread_blocks = p_vmthread;
+void set_TLS_data(VM_thread *thread) {
+ hythread_tls_set(hythread_self(), TLS_key_pvmthread, thread);
+ //printf ("sett ls call %p %p\n", get_thread_ptr(), get_vm_thread(hythread_self()));
+}
+IDATA jthread_throw_exception(char* name, char* message) {
+ exn_throw_by_name(name);
+ return 0;
}
-void tmn_thread_attach()
-{
- VM_thread *p_vmthread;
- p_vmthread = get_a_thread_block();
- VERIFY(p_vmthread, "Thread attach failure: can't get a thread block");
-// FIXME: following code should be incapsulated into thread manager component.
-#ifdef PLATFORM_POSIX
- p_vmthread->thread_handle = GetCurrentThreadId();
- p_vmthread->thread_id = GetCurrentThreadId();
-#else //PLATFORM_POSIX
- int UNUSED stat =
- DuplicateHandle(GetCurrentProcess(), // handle to process with handle to duplicate
- GetCurrentThread(), // handle to duplicate
- GetCurrentProcess(), // handle to process to duplicate to
- // gashiman - Duplicate handle does not do anything on linux
- // so it is safe to put type convertion here
- (VmEventHandle*)(&(p_vmthread->thread_handle)), // pointer to duplicate handle
- 0, // access for duplicate handle
- false, // handle inheritance flag
- DUPLICATE_SAME_ACCESS // optional actions
- );
- assert(stat);
-#endif //!PLATFORM_POSIX
+/**
+ * This file contains the functions which eventually should become part of vmcore.
+ * This localizes the dependencies of Thread Manager on vmcore component.
+ */
- set_TLS_data(p_vmthread);
-} //init_thread_block
-void tm_acquire_tm_lock(){
- p_thread_lock->_lock();
+void *vm_object_get_lockword_addr(jobject monitor){
+ return (*(ManagedObject**)monitor)->get_obj_info_addr();
}
-void tm_release_tm_lock(){
- p_thread_lock->_unlock();
+extern "C" char *vm_get_object_class_name(void* ptr) {
+ return (char*) (((ManagedObject*)ptr)->vt()->clss->name->bytes);
}
-bool tm_try_acquire_tm_lock(){
- return p_thread_lock->_tryLock();
+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;
}
-tm_iterator_t * tm_iterator_create()
-{
- assert(tmn_is_suspend_enabled());
- tm_acquire_tm_lock();
- tm_iterator_t * iterator = (tm_iterator_t *) malloc(sizeof(tm_iterator_t));
- assert(iterator);
- iterator->current = p_active_threads_list;
- iterator->init = true;
- return iterator;
+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);
}
-int tm_iterator_release(tm_iterator_t * iterator)
+JNIEnv * get_jnienv(void)
{
- free(iterator);
- tm_release_tm_lock();
- return 0;
+ return (JNIEnv*)jni_native_intf;
}
-int tm_iterator_reset(tm_iterator_t * iterator)
-{
- iterator->current = p_active_threads_list;
- iterator->init = true;
+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;
}
-
-VM_thread * tm_iterator_next(tm_iterator_t * iterator)
-{
- if (iterator->init) {
- iterator->init = false;
- } else if (iterator->current) {
- iterator->current = iterator->current->p_active;
+ return obj1->object == obj2->object;
}
- return iterator->current;
+
+int ti_is_enabled(){
+ return VM_Global_State::loader_env->TI->isEnabled();
}
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/verify_stack_enumeration.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/verify_stack_enumeration.cpp?rev=434076&r1=434075&r2=434076&view=diff
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/verify_stack_enumeration.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/verify_stack_enumeration.cpp Wed Aug 23 09:48:41 2006
@@ -114,7 +114,7 @@
if (NULL == heap_ceiling) { heap_ceiling = gc_heap_ceiling_address(); }
// GC must be prevented from happening while we hijack the GC functions
- assert(!tmn_is_suspend_enabled());
+ assert(!hythread_is_suspend_enabled());
// save away the GC function pointer
add_root_set_entry_func gc_add_root_set_entry_saved
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/compile_IA32.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/compile_IA32.cpp?rev=434076&r1=434075&r2=434076&view=diff
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/compile_IA32.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/compile_IA32.cpp Wed Aug 23 09:48:41 2006
@@ -52,7 +52,7 @@
#include "nogc.h"
#include "open/gc.h"
-#include "open/thread.h"
+
#include "open/vm_util.h"
#include "vm_synch.h"
@@ -95,7 +95,7 @@
void compile_protect_arguments(Method_Handle method, GcFrame* gc)
{
- assert(!tmn_is_suspend_enabled());
+ assert(!hythread_is_suspend_enabled());
Method_Signature_Handle msh = method_get_signature(method);
unsigned num_args = method_args_get_number(msh);
unsigned num_arg_words = ((Method*)method)->get_num_arg_bytes()>>2;