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(&current->_gc_private_information);
-
-        printer(out);
-    }
-    
-    free_this_thread_block(current);
-    set_TLS_data(NULL);
-    gc_thread_kill(&current->_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;