harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gshiman...@apache.org
Subject svn commit: r597138 [12/15] - in /harmony/enhanced/drlvm/trunk: build/make/ build/make/components/vm/ vm/include/ vm/include/open/ vm/jitrino/src/codegenerator/ia32/ vm/port/src/encoder/ia32_em64t/ vm/port/src/lil/ia32/pim/ vm/tests/ncai/ vm/tests/ncai...
Date Wed, 21 Nov 2007 16:29:54 GMT
Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/linux/os_thread.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/linux/os_thread.c?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/linux/os_thread.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/linux/os_thread.c Wed Nov 21 08:29:40 2007
@@ -23,6 +23,8 @@
 #include <sched.h>		// sched_param
 #include <semaphore.h>
 #include <unistd.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
 
 #include "thread_private.h"
 
@@ -132,14 +134,6 @@
 }
 
 /**
- * Terminates the os thread.
- */
-int os_thread_cancel(osthread_t os_thread)
-{
-    return pthread_cancel(os_thread);
-}
-
-/**
  * Joins the os thread.
  *
  * @param os_thread     thread handle
@@ -162,27 +156,6 @@
     pthread_exit((void*)status);
 }
 
-static int yield_other_init_flag = 0;
-static sem_t yield_other_sem;
-
-static void yield_other_handler(int signum, siginfo_t* info, void* context) {
-    if (!yield_other_init_flag) return;
-    sem_post(&yield_other_sem);
-}
-
-static void init_thread_yield_other () {
-    struct sigaction sa;
-
-    // init notification semaphore
-    sem_init(&yield_other_sem, 0, 0);
-
-    // set signal handler
-    sigemptyset(&sa.sa_mask);
-    sa.sa_flags = SA_SIGINFO | SA_RESTART;
-    sa.sa_sigaction = yield_other_handler;
-    sigaction(SIGUSR2, &sa, NULL);
-}
-
 /**
  * Calculates absolute time in future for sem_timedwait timeout.
  * @param ptime The pointer to time structure to fill
@@ -202,36 +175,6 @@
 }
 
 /**
- * Sends a signal to a thread to make sure thread's write
- * buffers are flushed.
- */
-void os_thread_yield_other(osthread_t os_thread) {
-    static pthread_mutex_t yield_other_mutex = PTHREAD_MUTEX_INITIALIZER;
-    struct timespec timeout;
-    int r;
-
-    get_exceed_time(&timeout, 1000000L);
-
-    pthread_mutex_lock(&yield_other_mutex);
-
-    if (!yield_other_init_flag) {
-        init_thread_yield_other();
-        yield_other_init_flag = 1;
-    }
-
-    assert(os_thread);
-    r = pthread_kill(os_thread, SIGUSR2);
-
-    if (r == 0) {
-	// signal sent, let's do timed wait to make sure the signal
-	// was actually delivered
-        sem_timedwait(&yield_other_sem, &timeout);
-    }
-
-    pthread_mutex_unlock(&yield_other_mutex);
-}
-
-/**
  * Queries amount of user and kernel times consumed by the thread,
  * in nanoseconds.
  *
@@ -277,4 +220,481 @@
 
     return common_stack_size;
 
+}
+
+
+typedef enum
+{
+    THREADREQ_NONE = 0,
+    THREADREQ_SUS = 1,
+    THREADREQ_RES = 2,
+    THREADREQ_YIELD = 3
+} os_suspend_req_t;
+
+typedef struct os_thread_info_t os_thread_info_t;
+
+struct os_thread_info_t
+{
+    osthread_t              thread;
+    int                     suspend_count;
+    sem_t                   wake_sem;       /* to sem_post from signal handler */
+    os_thread_context_t     context;
+
+    os_thread_info_t*       next;
+};
+
+
+/* Global mutex to syncronize access to os_thread_info_t list */
+static pthread_mutex_t g_suspend_mutex;
+/* Global list with suspended threads info */
+static os_thread_info_t* g_suspended_list;
+/* request type for signal handler */
+os_suspend_req_t g_req_type;
+/* The thread which is processed */
+static osthread_t g_suspendee;
+/* Semaphore used to inform signal sender about signal delivery */
+static sem_t g_yield_sem;
+
+
+/* Forward declarations */
+static int suspend_init();
+static int suspend_init_lock();
+static os_thread_info_t* init_susres_list_item();
+static os_thread_info_t* suspend_add_thread(osthread_t thread);
+static void suspend_remove_thread(osthread_t thread);
+static os_thread_info_t* suspend_find_thread(osthread_t thread);
+static void sigusr2_handler(int signum, siginfo_t* info, void* context);
+
+
+/**
+ * Terminates the os thread.
+ */
+int os_thread_cancel(osthread_t os_thread)
+{
+    int status;
+    os_thread_info_t* pinfo;
+
+    if (!suspend_init_lock())
+        return TM_ERROR_INTERNAL;
+
+    pinfo = suspend_find_thread(os_thread);
+    status = pthread_cancel(os_thread);
+
+    if (pinfo && status == 0)
+        suspend_remove_thread(os_thread);
+
+    pthread_mutex_unlock(&g_suspend_mutex);
+    return status;
+}
+
+/**
+* Sends a signal to a thread to make sure thread's write
+ * buffers are flushed.
+ */
+void os_thread_yield_other(osthread_t os_thread) {
+    struct timespec timeout;
+    os_thread_info_t* pinfo;
+
+    if (!suspend_init_lock())
+        return;
+
+    pinfo = suspend_find_thread(os_thread);
+
+    if (pinfo && pinfo->suspend_count > 0) {
+        pthread_mutex_unlock(&g_suspend_mutex);
+        return;
+    }
+
+    g_suspendee = os_thread;
+    g_req_type = THREADREQ_YIELD;
+
+    assert(os_thread);
+    if (pthread_kill(os_thread, SIGUSR2) == 0) {
+        // signal sent, let's do timed wait to make sure the signal
+        // was actually delivered
+		get_exceed_time(&timeout, 1000000L);
+        sem_timedwait(&g_yield_sem, &timeout);
+    } else {
+        if (pinfo)
+            suspend_remove_thread(os_thread);
+    }
+
+    g_req_type = THREADREQ_NONE;
+    pthread_mutex_unlock(&g_suspend_mutex);
+}
+
+
+/**
+ * Suspend given thread
+ * @param thread The thread to suspend
+ */
+int os_thread_suspend(osthread_t thread)
+{
+    int status;
+    os_thread_info_t* pinfo;
+
+    if (!thread)
+        return TM_ERROR_NULL_POINTER;
+
+    if (!suspend_init_lock())
+        return TM_ERROR_INTERNAL;
+
+    pinfo = suspend_find_thread(thread);
+
+    if (!pinfo)
+        pinfo = suspend_add_thread(thread);
+
+    if (!pinfo)
+    {
+        pthread_mutex_unlock(&g_suspend_mutex);
+        return TM_ERROR_OUT_OF_MEMORY;
+    }
+
+    if (pinfo->suspend_count > 0)
+    {
+        ++pinfo->suspend_count;
+        pthread_mutex_unlock(&g_suspend_mutex);
+        return TM_ERROR_NONE;
+    }
+
+    g_suspendee = thread;
+    g_req_type = THREADREQ_SUS;
+
+    if (pthread_kill(thread, SIGUSR2) != 0)
+    {
+        suspend_remove_thread(thread);
+        pthread_mutex_unlock(&g_suspend_mutex);
+        return TM_ERROR_INTERNAL;
+    }
+
+    /* Waiting for suspendee response */
+    sem_wait(&pinfo->wake_sem);
+    /* Check result */
+    status = (pinfo->suspend_count > 0) ? TM_ERROR_NONE : TM_ERROR_INTERNAL;
+
+    pthread_mutex_unlock(&g_suspend_mutex);
+    return status;
+}
+
+/**
+ * Resume given thread
+ * @param thread The thread to resume
+ */
+int os_thread_resume(osthread_t thread)
+{
+    int status;
+    os_thread_info_t* pinfo;
+
+    if (!thread)
+        return TM_ERROR_NULL_POINTER;
+
+    if (!suspend_init_lock())
+        return TM_ERROR_INTERNAL;
+
+    pinfo = suspend_find_thread(thread);
+
+    if (!pinfo)
+    {
+        pthread_mutex_unlock(&g_suspend_mutex);
+        return TM_ERROR_UNATTACHED_THREAD;
+    }
+
+    if (pinfo->suspend_count > 1)
+    {
+        --pinfo->suspend_count;
+        pthread_mutex_unlock(&g_suspend_mutex);
+        return TM_ERROR_NONE;
+    }
+
+    g_suspendee = thread;
+    g_req_type = THREADREQ_RES;
+
+    if ((status = pthread_kill(thread, SIGUSR2)) != 0)
+    {
+        suspend_remove_thread(thread);
+        pthread_mutex_unlock(&g_suspend_mutex);
+        return status;
+    }
+
+    /* Waiting for resume notification */
+    sem_wait(&pinfo->wake_sem);
+
+    suspend_remove_thread(thread);
+
+    pthread_mutex_unlock(&g_suspend_mutex);
+    return TM_ERROR_NONE;
+}
+
+/**
+ * Determine suspend count for the given thread
+ * @param thread The thread to check
+ * @return -1 if error have occured
+ */
+int os_thread_get_suspend_count(osthread_t thread)
+{
+    os_thread_info_t* pinfo;
+    int suspend_count;
+
+    if (!thread)
+        return -1;
+
+    if (!suspend_init_lock())
+        return -1;
+
+    pinfo = suspend_find_thread(thread);
+
+    suspend_count = pinfo ? pinfo->suspend_count : 0;
+
+    pthread_mutex_unlock(&g_suspend_mutex);
+    return suspend_count;
+}
+
+/**
+ * Get context for given thread
+ * @param thread The thread to process
+ * @param context Pointer to platform-dependant context structure
+ * @note The thread must be suspended
+ */
+int os_thread_get_context(osthread_t thread, os_thread_context_t *context)
+{
+    int status = TM_ERROR_UNATTACHED_THREAD;
+    os_thread_info_t* pinfo;
+
+    if (!thread || !context)
+        return TM_ERROR_NULL_POINTER;
+
+    if (!suspend_init_lock())
+        return TM_ERROR_INTERNAL;
+
+    pinfo = suspend_find_thread(thread);
+
+    if (!pinfo)
+    {
+        pthread_mutex_unlock(&g_suspend_mutex);
+        return status;
+    }
+
+    if (pinfo->suspend_count > 0)
+    {
+        *context = pinfo->context;
+        status = TM_ERROR_NONE;
+    }
+
+    pthread_mutex_unlock(&g_suspend_mutex);
+    return status;
+}
+
+/**
+ * Set context for given thread
+ * @param thread The thread to process
+ * @param context Pointer to platform-dependant context structure
+ * @note The thread must be suspended
+ */
+int os_thread_set_context(osthread_t thread, os_thread_context_t *context)
+{
+    int status = TM_ERROR_UNATTACHED_THREAD;
+    os_thread_info_t* pinfo;
+
+    if (!thread || !context)
+        return TM_ERROR_NULL_POINTER;
+
+    if (!suspend_init_lock())
+        return TM_ERROR_INTERNAL;
+
+    pinfo = suspend_find_thread(thread);
+
+    if (!pinfo)
+    {
+        pthread_mutex_unlock(&g_suspend_mutex);
+        return status;
+    }
+
+    if (pinfo->suspend_count > 0)
+    {
+        pinfo->context = *context;
+        status = TM_ERROR_NONE;
+    }
+
+    pthread_mutex_unlock(&g_suspend_mutex);
+    return status;
+}
+
+
+static int suspend_init()
+{
+    static int initialized = 0;
+    struct sigaction sa;
+    static pthread_mutex_t suspend_init_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+    if (initialized)
+        return 1;
+
+    pthread_mutex_lock(&suspend_init_mutex);
+
+    if (!initialized)
+    {
+        /* Initialize all nesessary objects */
+        int status;
+        pthread_mutex_t mut_init = PTHREAD_MUTEX_INITIALIZER;
+
+        status = sem_init(&g_yield_sem, 0, 0);
+
+        if (status != 0)
+        {
+            pthread_mutex_unlock(&suspend_init_mutex);
+            return 0;
+        }
+
+        g_suspend_mutex = mut_init;
+        pthread_mutex_init(&g_suspend_mutex, NULL);
+
+        g_suspended_list = NULL;
+        g_req_type = THREADREQ_NONE;
+
+        /* set signal handler */
+        sigemptyset(&sa.sa_mask);
+        sa.sa_flags = SA_SIGINFO | SA_RESTART;
+        sa.sa_sigaction = sigusr2_handler;
+        sigaction(SIGUSR2, &sa, NULL);
+
+        initialized = 1;
+    }
+
+    pthread_mutex_unlock(&suspend_init_mutex);
+    return 1;
+}
+
+static int suspend_init_lock()
+{
+    if (!suspend_init())
+        return 0;
+
+    if (pthread_mutex_lock(&g_suspend_mutex) != 0)
+        return 0;
+
+    return 1;
+}
+
+static os_thread_info_t* init_susres_list_item()
+{
+    os_thread_info_t* pinfo =
+        (os_thread_info_t*)malloc(sizeof(os_thread_info_t));
+
+    if (pinfo == NULL)
+        return NULL;
+
+    pinfo->suspend_count = 0;
+
+    int status = sem_init(&pinfo->wake_sem, 0, 0);
+
+    if (status != 0)
+    {
+        free(pinfo);
+        return NULL;
+    }
+
+    return pinfo;
+}
+
+static os_thread_info_t* suspend_add_thread(osthread_t thread)
+{
+    os_thread_info_t* pinfo = init_susres_list_item();
+
+    if (pinfo == NULL)
+        return NULL;
+
+    pinfo->thread = thread;
+    pinfo->next = g_suspended_list;
+    g_suspended_list = pinfo;
+    return pinfo;
+}
+
+static void suspend_remove_thread(osthread_t thread)
+{
+    os_thread_info_t** pprev = &g_suspended_list;
+    os_thread_info_t* pinfo;
+
+    for (pinfo = g_suspended_list; pinfo; pinfo = pinfo->next)
+    {
+        if (pinfo->thread == thread)
+            break;
+
+        pprev = &pinfo->next;
+    }
+
+    if (pinfo != NULL)
+    {
+        sem_destroy(&pinfo->wake_sem);
+        *pprev = pinfo->next;
+        free(pinfo);
+    }
+}
+
+static os_thread_info_t* suspend_find_thread(osthread_t thread)
+{
+    os_thread_info_t* pinfo;
+    int status;
+
+    for (pinfo = g_suspended_list; pinfo; pinfo = pinfo->next)
+    {
+        if (pinfo->thread == thread)
+            break;
+    }
+
+    return pinfo;
+}
+
+
+static void sigusr2_handler(int signum, siginfo_t* info, void* context)
+{
+    int status;
+    os_thread_info_t* pinfo;
+
+    if (!suspend_init())
+        return;
+
+    if (signum != SIGUSR2)
+        return;
+
+    /* We have g_suspend_mutex locked already */
+
+    if (g_req_type == THREADREQ_YIELD)
+    {
+        g_req_type = THREADREQ_NONE;
+        /* Inform requester */
+        sem_post(&g_yield_sem);
+        return;
+    }
+
+    if ((pinfo = suspend_find_thread(g_suspendee)) == NULL)
+        return;
+
+    if (g_req_type == THREADREQ_SUS)
+    {
+        pinfo->suspend_count++;
+        g_req_type = THREADREQ_NONE;
+        memcpy(&pinfo->context, context, sizeof(ucontext_t));
+        /* Inform suspender */
+        sem_post(&pinfo->wake_sem);
+
+        do
+        {
+            sigset_t sig_set;
+            sigemptyset(&sig_set);
+            sigsuspend(&sig_set);
+
+        } while (pinfo->suspend_count > 0);
+
+        /* We have returned from THREADREQ_RES handler */
+        memcpy(context, &pinfo->context, sizeof(ucontext_t));
+        /* Inform suspender */
+        sem_post(&pinfo->wake_sem);
+        return;
+    }
+    else if (g_req_type == THREADREQ_RES)
+    {
+        pinfo->suspend_count--;
+        g_req_type = THREADREQ_NONE;
+        return; /* Return to interrupted THREADREQ_SUS handler */
+    }
 }

Added: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ncai_common.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ncai_common.c?rev=597138&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ncai_common.c (added)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ncai_common.c Wed Nov 21 08:29:40 2007
@@ -0,0 +1,108 @@
+/**
+ * @author Ilya Berezhniuk
+ * @version $Revision$
+ */
+
+/**
+ * @file thread_ncai_common.c
+ * @brief NCAI basic thread functions
+ */
+
+#include <open/hythread_ext.h>
+#include "thread_private.h"
+#include <open/ncai_thread.h>
+#include <open/jthread.h>
+
+
+/**
+ * Suspend thread as OS native thread.
+ *
+ * @param[in] thread The thread to suspend.
+ */
+IDATA VMCALL hythread_suspend_thread_native(hythread_t thread)
+{
+    if (thread == NULL)
+        return TM_ERROR_NULL_POINTER;
+
+    if (!hythread_is_alive(thread))
+        return TM_ERROR_INTERNAL;
+
+    assert(thread->os_handle);
+
+    return os_thread_suspend(thread->os_handle);
+}
+
+/**
+ * Resume thread as OS native thread.
+ *
+ * @param[in] thread The thread to resume.
+ */
+IDATA VMCALL hythread_resume_thread_native(hythread_t thread)
+{
+    if (thread == NULL)
+        return TM_ERROR_NULL_POINTER;
+
+    if (!hythread_is_alive(thread))
+        return TM_ERROR_INTERNAL;
+
+    assert(thread->os_handle);
+
+    return os_thread_resume(thread->os_handle);
+}
+
+/**
+ * Returns suspend count for given thread.
+ *
+ * @param[in] thread The thread to process.
+ * @return -1 if error have occured
+ */
+int VMCALL hythread_get_suspend_count_native(hythread_t thread)
+{
+    if (thread == NULL)
+        return -1;
+
+    if (!hythread_is_alive(thread))
+        return -1;
+
+    assert(thread->os_handle);
+
+    return os_thread_get_suspend_count(thread->os_handle);
+}
+
+/**
+ * Returns the platform-dependent thread context.
+ *
+ * @param[in] thread to get context.
+ * @param[out] pointer to context structure.
+ */
+IDATA VMCALL hythread_get_thread_context(hythread_t thread, os_thread_context_t* pcontext)
+{
+    if (pcontext == NULL || thread == NULL)
+        return TM_ERROR_NULL_POINTER;
+
+    if (!hythread_is_alive(thread))
+        return TM_ERROR_INTERNAL;
+
+    assert(thread->os_handle);
+
+    return os_thread_get_context(thread->os_handle, pcontext);
+}
+
+/**
+ * Sets the context for given thread.
+ *
+ * @param[in] thread to set context.
+ * @param[in] pointer to context structure.
+ */
+IDATA VMCALL hythread_set_thread_context(hythread_t thread, os_thread_context_t* pcontext)
+{
+    if (pcontext == NULL || thread == NULL)
+        return TM_ERROR_NULL_POINTER;
+
+    if (!hythread_is_alive(thread))
+        return TM_ERROR_INTERNAL;
+
+    assert(thread->os_handle);
+
+    return os_thread_get_context(thread->os_handle, pcontext);
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ncai_common.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h Wed Nov 21 08:29:40 2007
@@ -22,6 +22,7 @@
 #include <open/types.h>
 #include <open/hythread_ext.h>
 #include <open/ti_thread.h>
+#include <open/ncai_thread.h>
 #include <apr_pools.h>
 #include <apr_thread_mutex.h>
 #include <apr_thread_cond.h>
@@ -316,6 +317,12 @@
 
 int os_cond_timedwait(hycond_t *cond, hymutex_t *mutex, I_64 ms, IDATA nano);
 UDATA os_get_foreign_thread_stack_size();
+
+int os_thread_suspend(osthread_t thread);
+int os_thread_resume(osthread_t thread);
+int os_thread_get_suspend_count(osthread_t thread);
+int os_thread_get_context(osthread_t thread, os_thread_context_t *context);
+int os_thread_set_context(osthread_t thread, os_thread_context_t *context);
 
 #ifdef __cplusplus
 }

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/win/os_thread.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/win/os_thread.c?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/win/os_thread.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/win/os_thread.c Wed Nov 21 08:29:40 2007
@@ -84,17 +84,6 @@
 }
 
 /**
- * Terminates the os thread.
- */
-int os_thread_cancel(osthread_t os_thread)
-{
-    if (TerminateThread(os_thread, 0))
-        return 0;
-    else
-        return GetLastError();
-}
-
-/**
  * Joins the os thread.
  *
  * @param os_thread     thread handle
@@ -125,37 +114,6 @@
 }
 
 /**
- * Causes the other thread to have a memory barrier by suspending
- * and resuming it.
- */
-void os_thread_yield_other(osthread_t os_thread)
-{
-    static CRITICAL_SECTION yield_other_mutex;
-    static int initialized = 0;
-    if (!initialized) {
-        // Critical section should be initialized only once,
-        // do nothing in case someone else already initialized it.
-        if (apr_atomic_cas32((volatile uint32*)&initialized, 1, 0) == 0) {
-            InitializeCriticalSectionAndSpinCount(&yield_other_mutex, 400);
-        }
-    }
-
-    // FIXME: should not use yield_other_mutex until it is guaranteed to be initialized
-
-    /*
-     * Synchronization is needed to avoid cyclic (mutual) suspension problem.
-     * Accordingly to MSDN, it is possible on multiprocessor box that
-     * 2 threads suspend each other and become deadlocked.
-     */
-    EnterCriticalSection(&yield_other_mutex);
-    if (SuspendThread(os_thread) != -1) {
-        /* suspended successfully, so resume it back. */
-        ResumeThread(os_thread);
-    }
-    LeaveCriticalSection(&yield_other_mutex);
-}
-
-/**
  * Queries amount of user and kernel times consumed by the thread,
  * in nanoseconds.
  *
@@ -202,3 +160,353 @@
 
     return (UDATA)stack_size;
 }
+
+typedef struct os_thread_info_t os_thread_info_t;
+
+struct os_thread_info_t
+{
+    osthread_t              thread;
+    int                     suspend_count;
+    os_thread_context_t     context;
+
+    os_thread_info_t*       next;
+};
+
+
+static CRITICAL_SECTION g_crit_section;
+static os_thread_info_t* g_suspended_list = NULL;
+
+/* Forward declarations */
+static int suspend_init_lock();
+static os_thread_info_t* init_susres_list_item();
+static os_thread_info_t* suspend_add_thread(osthread_t thread);
+static void suspend_remove_thread(osthread_t thread);
+static os_thread_info_t* suspend_find_thread(osthread_t thread);
+
+
+/**
+ * Terminates the os thread.
+ */
+int os_thread_cancel(osthread_t os_thread)
+{
+    os_thread_info_t* pinfo;
+    int status = TM_ERROR_NONE;
+
+    if (!suspend_init_lock())
+        return TM_ERROR_INTERNAL;
+
+    pinfo = suspend_find_thread(os_thread);
+
+    if (pinfo)
+        suspend_remove_thread(os_thread);
+
+    if (!TerminateThread(os_thread, 0))
+        status = (int)GetLastError();
+
+    LeaveCriticalSection(&g_crit_section);
+    return status;
+}
+
+/**
+ * Causes the other thread to have a memory barrier by suspending
+ * and resuming it.
+ */
+void os_thread_yield_other(osthread_t os_thread)
+{
+    os_thread_info_t* pinfo;
+
+    /*
+     * Synchronization is needed to avoid cyclic (mutual) suspension problem.
+     * Accordingly to MSDN, it is possible on multiprocessor box that
+     * 2 threads suspend each other and become deadlocked.
+     */
+    if (!suspend_init_lock()) // Initializes and enters a critical section
+        return;
+
+    pinfo = suspend_find_thread(os_thread);
+
+    if (pinfo && pinfo->suspend_count > 0) {
+        LeaveCriticalSection(&g_crit_section);
+        return;
+    }
+
+    if (SuspendThread(os_thread) != -1) {
+        /* suspended successfully, so resume it back. */
+        ResumeThread(os_thread);
+    }
+
+    LeaveCriticalSection(&g_crit_section);
+}
+
+
+/**
+ * Suspend given thread
+ * @param thread The thread to suspend
+ */
+int os_thread_suspend(osthread_t thread)
+{
+    os_thread_info_t* pinfo;
+    DWORD old_count;
+
+    if (!thread)
+        return TM_ERROR_NULL_POINTER;
+
+    if (!suspend_init_lock())
+        return TM_ERROR_INTERNAL;
+
+    pinfo = suspend_find_thread(thread);
+
+    if (!pinfo)
+        pinfo = suspend_add_thread(thread);
+
+    if (!pinfo)
+    {
+        LeaveCriticalSection(&g_crit_section);
+        return TM_ERROR_OUT_OF_MEMORY;
+    }
+
+    if (pinfo->suspend_count > 0)
+    {
+        ++pinfo->suspend_count;
+        LeaveCriticalSection(&g_crit_section);
+        return TM_ERROR_NONE;
+    }
+
+    old_count = SuspendThread(thread);
+
+    if (old_count == (DWORD)-1)
+    {
+        int status = (int)GetLastError();
+        LeaveCriticalSection(&g_crit_section);
+        return status;
+    }
+
+    ++pinfo->suspend_count;
+    LeaveCriticalSection(&g_crit_section);
+    return TM_ERROR_NONE;
+}
+
+/**
+ * Resume given thread
+ * @param thread The thread to resume
+ */
+int os_thread_resume(osthread_t thread)
+{
+    os_thread_info_t* pinfo;
+    DWORD old_count;
+
+    if (!thread)
+        return TM_ERROR_NULL_POINTER;
+
+    if (!suspend_init_lock())
+        return TM_ERROR_INTERNAL;
+
+    pinfo = suspend_find_thread(thread);
+
+    if (!pinfo)
+    {
+        LeaveCriticalSection(&g_crit_section);
+        return TM_ERROR_UNATTACHED_THREAD;
+    }
+
+    if (pinfo->suspend_count > 1)
+    {
+        --pinfo->suspend_count;
+        LeaveCriticalSection(&g_crit_section);
+        return TM_ERROR_NONE;
+    }
+
+    old_count = ResumeThread(thread);
+
+    if (old_count == (DWORD)-1)
+    {
+        int status = (int)GetLastError();
+        LeaveCriticalSection(&g_crit_section);
+        return status;
+    }
+
+    if (--pinfo->suspend_count == 0)
+        suspend_remove_thread(thread);
+
+    LeaveCriticalSection(&g_crit_section);
+    return TM_ERROR_NONE;
+}
+
+/**
+ * Determine suspend count for the given thread
+ * @param thread The thread to check
+ * @return -1 if error have occured
+ */
+int os_thread_get_suspend_count(osthread_t thread)
+{
+    os_thread_info_t* pinfo;
+    int suspend_count;
+
+    if (!thread)
+        return -1;
+
+    if (!suspend_init_lock())
+        return -1;
+
+    pinfo = suspend_find_thread(thread);
+    suspend_count = pinfo ? pinfo->suspend_count : 0;
+
+    LeaveCriticalSection(&g_crit_section);
+    return suspend_count;
+}
+
+/**
+ * Get context for given thread
+ * @param thread The thread to process
+ * @param context Pointer to platform-dependant context structure
+ * @note The thread must be suspended
+ */
+int os_thread_get_context(osthread_t thread, os_thread_context_t *context)
+{
+    os_thread_info_t* pinfo;
+    CONTEXT local_context;
+
+    if (!thread || !context)
+        return TM_ERROR_NULL_POINTER;
+
+    if (!suspend_init_lock())
+        return TM_ERROR_INTERNAL;
+
+    pinfo = suspend_find_thread(thread);
+
+    if (!pinfo)
+    {
+        LeaveCriticalSection(&g_crit_section);
+        return TM_ERROR_UNATTACHED_THREAD;
+    }
+
+#ifdef CONTEXT_ALL
+    local_context.ContextFlags = CONTEXT_ALL;
+#else
+    local_context.ContextFlags = CONTEXT_FULL;
+#endif
+
+    if (!GetThreadContext(thread, &local_context))
+    {
+        int status = (int)GetLastError();
+        LeaveCriticalSection(&g_crit_section);
+        return status;
+    }
+
+    pinfo->context = local_context;
+    *context = local_context;
+    LeaveCriticalSection(&g_crit_section);
+    return TM_ERROR_NONE;
+}
+
+/**
+ * Set context for given thread
+ * @param thread The thread to process
+ * @param context Pointer to platform-dependant context structure
+ * @note The thread must be suspended
+ */
+int os_thread_set_context(osthread_t thread, os_thread_context_t *context)
+{
+    os_thread_info_t* pinfo;
+
+    if (!thread || !context)
+        return -1;
+
+    if (!suspend_init_lock())
+        return -2;
+
+    pinfo = suspend_find_thread(thread);
+
+    if (!pinfo)
+    {
+        LeaveCriticalSection(&g_crit_section);
+        return TM_ERROR_UNATTACHED_THREAD;
+    }
+
+    if (!SetThreadContext(thread, context))
+    {
+        int status = (int)GetLastError();
+        LeaveCriticalSection(&g_crit_section);
+        return status;
+    }
+
+    pinfo->context = *context;
+    LeaveCriticalSection(&g_crit_section);
+    return TM_ERROR_NONE;
+}
+
+
+static int suspend_init_lock()
+{
+    static uint32 initialized = 0;
+
+    if (!initialized)
+    {
+        // Critical section should be initialized only once,
+        // do nothing in case someone else already initialized it.
+        if (apr_atomic_cas32((volatile uint32*)&initialized, 1, 0) == 0)
+            InitializeCriticalSectionAndSpinCount(&g_crit_section, 400);
+    }
+
+    EnterCriticalSection(&g_crit_section);
+    return 1;
+}
+
+static os_thread_info_t* init_susres_list_item()
+{
+    os_thread_info_t* pinfo =
+        (os_thread_info_t*)malloc(sizeof(os_thread_info_t));
+
+    if (pinfo)
+        pinfo->suspend_count = 0;
+
+    return pinfo;
+}
+
+static os_thread_info_t* suspend_add_thread(osthread_t thread)
+{
+    os_thread_info_t* pinfo = init_susres_list_item();
+
+    if (!pinfo)
+        return NULL;
+
+    pinfo->thread = thread;
+    pinfo->next = g_suspended_list;
+    g_suspended_list = pinfo;
+
+    return pinfo;
+}
+
+static void suspend_remove_thread(osthread_t thread)
+{
+    os_thread_info_t** pprev = &g_suspended_list;
+    os_thread_info_t* pinfo;
+
+    for (pinfo = g_suspended_list; pinfo; pinfo = pinfo->next)
+    {
+        if (pinfo->thread == thread)
+            break;
+
+        pprev = &pinfo->next;
+    }
+
+    if (pinfo)
+    {
+        *pprev = pinfo->next;
+        free(pinfo);
+    }
+}
+
+static os_thread_info_t* suspend_find_thread(osthread_t thread)
+{
+    os_thread_info_t* pinfo;
+
+    for (pinfo = g_suspended_list; pinfo; pinfo = pinfo->next)
+    {
+        if (pinfo->thread == thread)
+            break;
+    }
+
+    return pinfo;
+}
+

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/environment.h Wed Nov 21 08:29:40 2007
@@ -31,6 +31,7 @@
 #include "vm_core_types.h"
 #include "object_handles.h"
 #include "jvmti_internal.h"
+#include "ncai_internal.h"
 #include "method_lookup.h"
 
 typedef struct NSOTableItem NSOTableItem;
@@ -46,6 +47,7 @@
     BootstrapClassLoader*     bootstrap_class_loader;
     UserDefinedClassLoader*   system_class_loader;
     DebugUtilsTI*             TI;
+    GlobalNCAI*               NCAI;
     NSOTableItem*             nsoTable;
     void*                     portLib;  // Classlib's port library
     DynamicCode*              dcList;

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_break_intf.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_break_intf.h?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_break_intf.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_break_intf.h Wed Nov 21 08:29:40 2007
@@ -42,7 +42,9 @@
 
 // Callbacks are called for interfaces according to its priority
 typedef enum {
-    PRIORITY_SINGLE_STEP_BREAKPOINT = 0,
+    PRIORITY_NCAI_STEP_BREAKPOINT = 0,
+    PRIORITY_SINGLE_STEP_BREAKPOINT,
+    PRIORITY_NCAI_BREAKPOINT,
     PRIORITY_SIMPLE_BREAKPOINT,
     PRIORITY_NUMBER
 } jvmti_BreakPriority;
@@ -58,6 +60,7 @@
     jmethodID                method;
     jlocation                location;
     jbyte                    saved_byte;
+    Registers                regs;
 };
 
 // Breakpoint reference
@@ -75,6 +78,8 @@
     VMBreakInterface *intf;
     VMLocalBreak* next;
     unsigned priority;
+    VM_thread* vmthread;
+    VMBreakPoint *local_bp;
 };
 
 // Pointer to interface callback function
@@ -136,9 +141,16 @@
     VMBreakInterface* get_first_intf(unsigned priority) { return m_intf[priority]; }
     VMBreakInterface* get_next_intf(VMBreakInterface *intf);
 
+    // Breakpoints iterator
+    VMBreakPoint* get_first_breakpoint() { return m_break; }
+    VMBreakPoint* get_next_breakpoint(VMBreakPoint* prev);
+
     // General callback functions
     void  process_native_breakpoint();
     jbyte process_interpreter_breakpoint(jmethodID method, jlocation location);
+
+    // Find thread-local breakpoint information
+    VMLocalBreak* find_thread_local_break(VM_thread* vmthread);
 
 private:
     // Checks breakpoint before inserting

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_dasm.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_dasm.h?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_dasm.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_dasm.h Wed Nov 21 08:29:40 2007
@@ -43,7 +43,8 @@
         RELATIVE_COND_JUMP,
         RELATIVE_CALL,
         INDIRECT_JUMP,
-        INDIRECT_CALL
+        INDIRECT_CALL,
+        RET
     };
     /**
      * General-purpose registers set.

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h Wed Nov 21 08:29:40 2007
@@ -44,6 +44,8 @@
 // declared privately in jvmti_heap.h
 struct TIIterationState;
 
+struct NCAIEnv;
+
 /*
  * Type that describes TI environment created by GetEnv function
  */
@@ -64,6 +66,7 @@
     TITags* tags;
     TIIterationState* iteration_state;
     TIEnv* next;
+    NCAIEnv *ncai_env;
 
     bool global_events[TOTAL_EVENT_TYPE_NUM];
     TIEventThread *event_threads[TOTAL_EVENT_TYPE_NUM];

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h Wed Nov 21 08:29:40 2007
@@ -414,6 +414,9 @@
     jvmti_thread_t jvmti_thread, Method* method);
 void jvmti_remove_single_step_breakpoints(DebugUtilsTI *ti, jvmti_thread_t jvmti_thread);
 
+// NCAI extension
+jvmtiError JNICALL jvmtiGetNCAIEnvironment(jvmtiEnv* jvmti_env, ...);
+
 // Object check functions
 Boolean is_valid_throwable_object(jthread thread);
 Boolean is_valid_thread_object(jthread thread);

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/natives_support.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/natives_support.h?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/natives_support.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/natives_support.h Wed Nov 21 08:29:40 2007
@@ -130,4 +130,15 @@
 void
 natives_describe_error(NativeLoadStatus error, char* buf, size_t buflen);
 
+
+/**
+ * Function detects if module is JNI library
+ *
+ * @param libname        - library name (full or relative)
+ *
+ * @return true if specified library was loaded already by natives support
+ */
+//
+bool natives_is_library_loaded_slow(const char* libname);
+
 #endif // _NATIVES_SUPPORT_LIB_H_

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_direct.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_direct.h?rev=597138&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_direct.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_direct.h Wed Nov 21 08:29:40 2007
@@ -0,0 +1,278 @@
+#ifndef _NCAI_DIRECT_H_
+#define _NCAI_DIRECT_H_
+
+#include "jvmti_direct.h"
+#include "lock_manager.h"
+#include "ncai.h"
+#include "open/hythread.h"
+
+
+struct ncaiEventThread
+{
+    ncaiThread thread;
+    ncaiEventThread* next;
+};
+
+// ncaiThread=(_ncaiThread*) will be used as hythread_t=(HyThread*)
+struct _ncaiThread
+{
+    int dummy; // The structure will never be allocated
+};
+
+struct _ncaiModule{
+    ncaiModuleInfo* info;
+    _ncaiModule* next;
+    bool isAlive;
+};
+
+class VMBreakInterface;
+
+struct NCAIEnv
+{
+    const _ncai *functions;
+    TIEnv *ti_env;
+    Lock_Manager* env_lock;
+    ncaiModule modules;
+    ncaiEventCallbacks event_table;
+    VMBreakInterface* brpt_intf;
+
+    bool global_events[NCAI_MAX_EVENT_TYPE_VAL - NCAI_MIN_EVENT_TYPE_VAL + 1];
+    ncaiEventThread *event_threads[NCAI_MAX_EVENT_TYPE_VAL - NCAI_MIN_EVENT_TYPE_VAL + 1];
+
+    /**
+     * Returns pointer to a callback function that was set by SetEventCallbacks
+     * If no callback was set, this function returns NULL, in this case
+     * no event should be sent.
+     */
+    void *get_event_callback(ncaiEventKind event_type)
+    {
+        return ((void **)&event_table)[event_type - NCAI_MIN_EVENT_TYPE_VAL];
+    }
+
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    ncaiError JNICALL ncaiGetAllLoadedModules(ncaiEnv* env,
+        jint* count_ptr,
+        ncaiModule** modules_ptr);
+
+    ncaiError JNICALL ncaiGetModuleInfo(ncaiEnv* env,
+        ncaiModule module,
+        ncaiModuleInfo* info_ptr);
+
+    ncaiError JNICALL ncaiGetModuleClassLoader(ncaiEnv* env,
+        ncaiModule module,
+        jobject* classloader_ptr);
+
+    ncaiError JNICALL ncaiIsMethodCompiled(ncaiEnv* env,
+        jmethodID method,
+        jboolean* is_compiled_ptr);
+
+    ncaiError JNICALL ncaiGetMethodLocation(ncaiEnv* env,
+        jmethodID method,
+        void** address_ptr,
+        size_t* size_ptr);
+
+    ncaiError JNICALL ncaiFindJavaMethod(ncaiEnv* env,
+        void* address,
+        jmethodID* method_ptr);
+
+    ncaiError JNICALL ncaiGetBytcodeLocation(ncaiEnv* env,
+        void* address,
+        jmethodID* method,
+        jlocation* location_ptr);
+
+    ncaiError JNICALL ncaiGetNativeLocation(ncaiEnv* env,
+        jmethodID method,
+        jlocation location,
+        void** address_ptr);
+
+    ncaiError JNICALL ncaiGetAllThreads(ncaiEnv* env,
+        jint* count_ptr,
+        ncaiThread** threads_ptr);
+
+    ncaiError JNICALL ncaiGetThreadInfo(ncaiEnv* env,
+        ncaiThread thread,
+        ncaiThreadInfo* info_ptr);
+
+    ncaiError JNICALL ncaiGetThreadHandle(ncaiEnv* env,
+        jthread thread,
+        ncaiThread* thread_ptr);
+
+    ncaiError JNICALL ncaiGetThreadObject(ncaiEnv* env,
+        ncaiThread thread,
+        jthread* thread_ptr);
+
+    ncaiError JNICALL ncaiSuspendThread(ncaiEnv* env,
+        ncaiThread thread);
+
+    ncaiError JNICALL ncaiResumeThread(ncaiEnv* env,
+        ncaiThread thread);
+
+    ncaiError JNICALL ncaiTerminateThread(ncaiEnv* env,
+        ncaiThread thread);
+
+    ncaiError JNICALL ncaiGetThreadState(ncaiEnv* env,
+        ncaiThread thread,
+        jint* state_ptr);
+
+    ncaiError JNICALL ncaiGetFrameCount(ncaiEnv* env,
+        ncaiThread thread,
+        jint* count_ptr);
+
+    ncaiError JNICALL ncaiGetStackTrace(ncaiEnv* env,
+        ncaiThread thread,
+        jint depth,
+        ncaiFrameInfo* frame_buffer,
+        jint* count_ptr);
+
+    ncaiError JNICALL ncaiGetRegisterCount(ncaiEnv* env,
+        jint* count_ptr);
+
+    ncaiError JNICALL ncaiGetRegisterInfo(ncaiEnv* env,
+        jint reg_number,
+        ncaiRegisterInfo* info_ptr);
+
+    ncaiError JNICALL ncaiGetRegisterValue(ncaiEnv* env,
+        ncaiThread thread,
+        jint reg_number,
+        void* buf);
+
+    ncaiError JNICALL ncaiSetRegisterValue(ncaiEnv* env,
+        ncaiThread thread,
+        jint reg_number,
+        void* buf);
+
+    ncaiError JNICALL ncaiReadMemory(ncaiEnv* env,
+        void* addr,
+        size_t size,
+        void* buf);
+
+    ncaiError JNICALL ncaiWriteMemory(ncaiEnv* env,
+        void* addr,
+        size_t size,
+        void* buf);
+
+    ncaiError JNICALL ncaiGetSignalCount(ncaiEnv* env,
+        jint* count_ptr);
+
+    ncaiError JNICALL ncaiGetSignalInfo(ncaiEnv* env,
+        jint signal,
+        ncaiSignalInfo* info_ptr);
+
+    ncaiError JNICALL ncaiGetJvmtiEnv(ncaiEnv* env,
+        jvmtiEnv** jvmti_env_ptr);
+
+    ncaiError JNICALL ncaiGetVersion(ncaiEnv* env,
+        jint* version_ptr);
+
+    ncaiError JNICALL ncaiGetErrorName(ncaiEnv* env,
+        ncaiError err,
+        const char** name_ptr);
+
+    ncaiError JNICALL ncaiGetPotentialCapabilities(ncaiEnv* env,
+        ncaiCapabilities* caps_ptr);
+
+    ncaiError JNICALL ncaiGetCapabilities(ncaiEnv* env,
+        ncaiCapabilities* caps_ptr);
+
+    ncaiError JNICALL ncaiAddCapabilities(ncaiEnv* env,
+        ncaiCapabilities* caps_ptr);
+
+    ncaiError JNICALL ncaiRelinquishCapabilities(ncaiEnv* env,
+        ncaiCapabilities* caps_ptr);
+
+    ncaiError JNICALL ncaiGetEventCallbacks(ncaiEnv* env,
+        ncaiEventCallbacks* callbacks,
+        size_t size);
+
+    ncaiError JNICALL ncaiSetEventCallbacks(ncaiEnv* env,
+        ncaiEventCallbacks* callbacks,
+        size_t size);
+
+    ncaiError JNICALL ncaiSetEventNotificationMode(ncaiEnv* env,
+        ncaiEventMode mode,
+        ncaiEventKind event,
+        ncaiThread thread);
+
+    ncaiError JNICALL ncaiSetBreakpoint(ncaiEnv* env,
+        void* code_addr);
+
+    ncaiError JNICALL ncaiClearBreakpoint(ncaiEnv* env,
+        void* code_addr);
+
+    ncaiError JNICALL ncaiSetWatchpoint(ncaiEnv* env,
+        void* data_addr,
+        size_t len,
+        ncaiWatchpointMode mode);
+
+    ncaiError JNICALL ncaiClearWatchpoint(ncaiEnv* env,
+        void* data_addr);
+
+    ncaiError JNICALL ncaiSetStepMode(ncaiEnv* env,
+        ncaiThread thread,
+        ncaiStepMode mode);
+
+    ncaiError JNICALL ncaiNotifyFramePop(ncaiEnv* env,
+        ncaiThread thread,
+        void* frame_address);
+
+/*    void JNICALL ncaiStep(ncaiEnv* env,
+        ncaiThread thread,
+        void* addr);
+
+    void JNICALL ncaiBreakpoint(ncaiEnv* env,
+        ncaiThread thread,
+        void* addr);
+
+    void JNICALL ncaiWatchpoint(ncaiEnv* env,
+        ncaiThread thread,
+        void* code_addr,
+        void* data_addr);
+
+    void JNICALL ncaiSignal(ncaiEnv* env,
+        ncaiThread thread,
+        void* addr,
+        jint signal,
+        jboolean is_internal,
+        jboolean* is_handled);
+
+    void JNICALL ncaiException(ncaiEnv* env,
+        ncaiThread thread,
+        void* addr,
+        void* exception);
+
+    void JNICALL ncaiModuleLoad(ncaiEnv* env,
+        ncaiThread thread,
+        ncaiModule module);
+
+    void JNICALL ncaiModuleUnload(ncaiEnv* env,
+        ncaiThread thread,
+        ncaiModule module);
+
+    void JNICALL ncaiMethodEntry(ncaiEnv* env,
+        ncaiThread thread,
+        void* addr);
+
+    void JNICALL ncaiMethodExit(ncaiEnv* env,
+        ncaiThread thread,
+        void* addr);
+
+    void JNICALL ncaiFramePop(ncaiEnv* env,
+        ncaiThread thread,
+        void* addr);
+
+    void JNICALL ncaiConsoleInput(ncaiEnv* env, char** message);
+
+    void JNICALL ncaiConsoleOutput(ncaiEnv* env, char* message);
+
+    void JNICALL ncaiDebugMessage(ncaiEnv* env, char* message);*/
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _NCAI_DIRECT_H_ */
+

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_direct.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h?rev=597138&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h Wed Nov 21 08:29:40 2007
@@ -0,0 +1,142 @@
+/**
+ * @author Ilya Berezhniuk
+ * @version $Revision$
+ */
+#ifndef _NCAI_INTERNAL_H_
+#define _NCAI_INTERNAL_H_
+
+#include "ncai.h"
+#include "open/ncai_thread.h"
+#include "ncai_direct.h"
+#include "vm_threads.h"
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _NcaiRegisterTableItem
+{
+    char*       name;       // Register name
+    jint        size;       // Register size in bytes
+    unsigned    offset;     // Register offset in NcaiRegisters structure
+
+} NcaiRegisterTableItem;
+
+// Register table is specific for target processor architecture
+extern NcaiRegisterTableItem g_ncai_reg_table[];
+
+
+int walk_native_stack(hythread_t thread,
+    VM_thread* pthread, int max_depth, ncaiFrameInfo* frame_info);
+
+void clean_all_modules(ncaiModule* pmodules);
+void ncai_library_load_callback(const char* name);
+void ncai_library_unload_callback(const char* name);
+
+
+// These functions are differ for various architectures
+size_t ncai_get_reg_table_size();
+bool ncai_get_register_value(hythread_t thread, jint reg_number, void* buf_ptr);
+bool ncai_set_register_value(hythread_t thread, jint reg_number, void* buf_ptr);
+void* ncai_get_instruction_pointer(hythread_t thread);
+
+// These functions are differ for various operating systems
+bool ncai_get_generic_registers(hythread_t handle, Registers* regs);
+char* ncai_parse_module_name(char* filepath);
+ncaiError ncai_read_memory(void* addr, size_t size, void* buf);
+ncaiError ncai_write_memory(void* addr, size_t size, void* buf);
+
+
+struct VMBreakPoint;
+
+// Callback function for NCAI breakpoint processing
+bool ncai_process_breakpoint_event(TIEnv *env, const VMBreakPoint* bp,
+                                    const POINTER_SIZE_INT data);
+
+
+/*
+ * Global NCAI data
+ */
+class GlobalNCAI
+{
+public:
+    bool    enabled; // Is NCAI enabled
+
+    bool step_enabled; // Is Single Stepping enabled
+    ncaiStepMode step_mode; // Global step mode
+
+    Lock_Manager mod_lock;
+    ncaiModule modules;
+
+public:
+    GlobalNCAI();
+    ~GlobalNCAI();
+
+    static bool isEnabled();
+
+}; /* end of GlobalNCAI */
+
+
+struct st_pending_ss;
+
+struct NCAISingleStepState
+{
+    // Predicted breakpoints
+    VMBreakInterface* breakpoints;
+    // Postponed breakpoints
+    st_pending_ss* pplist;
+    // Step mode: OFF/INTO/OVER/OUT
+    bool use_local_mode;
+    ncaiStepMode step_mode;
+    // Report STEP_OUT event if set
+    bool flag_out;
+};
+
+// Allocate thread-local structures for single step processing
+void ncai_check_alloc_ss_data(jvmti_thread_t jvmti_thread);
+
+// Functions to enable/disable single stepping if needed
+ncaiError ncai_start_single_step(NCAIEnv* env);
+ncaiError ncai_stop_single_step(NCAIEnv* env);
+bool ncai_start_thread_single_step(NCAIEnv* env, hythread_t thread);
+void ncai_stop_thread_single_step(jvmti_thread_t jvmti_thread);
+
+// Must be called under breakpoint lock
+ncaiStepMode ncai_get_thread_ss_mode(jvmti_thread_t jvmti_thread);
+
+// Returns type of specified adress
+ncaiModuleKind ncai_get_target_address_type(void* addr);
+// Instrument predicted locations for single step
+void ncai_setup_single_step(GlobalNCAI* ncai,
+            const VMBreakPoint* bp, jvmti_thread_t jvmti_thread);
+// Instrument predicted HWE handlers
+void ncai_setup_signal_step(jvmti_thread_t jvmti_thread, NativeCodePtr addr);
+
+// Function to send Signal events
+void ncai_process_signal_event(NativeCodePtr addr,
+        jint code, bool is_internal, bool* p_handled);
+
+// Method Entry/Exit events processing
+void ncai_report_method_entry(jmethodID method);
+void ncai_report_method_exit(jmethodID method, jboolean exc_popped, jvalue ret_val);
+void ncai_step_native_method_entry(Method* m);
+void ncai_step_native_method_exit(Method* m);
+
+
+// Platform-dependant Signal functions
+size_t ncai_get_signal_count();
+bool ncai_is_signal_in_range(jint signal);
+char* ncai_get_signal_name(jint signal);
+size_t ncai_get_signal_name_size(jint signal);
+
+// Allows to get modules without providing NCAI environment
+ncaiError ncai_get_all_loaded_modules(ncaiEnv *env,
+    jint *count_ptr, ncaiModule **modules_ptr);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _NCAI_INTERNAL_H_ */

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_internal.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_utils.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_utils.h?rev=597138&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_utils.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_utils.h Wed Nov 21 08:29:40 2007
@@ -0,0 +1,37 @@
+/**
+ * @author Ilya Berezhniuk
+ * @version $Revision$
+ */
+#ifndef _NCAI_UTILS_H_
+#define _NCAI_UTILS_H_
+
+#include "port_malloc.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+static inline void* ncai_alloc(size_t size)
+{
+    return STD_MALLOC(size);
+}
+
+static inline void* ncai_realloc(void* mem)
+{
+    return mem;
+}
+
+static inline void ncai_free(void* mem)
+{
+    STD_FREE(mem);
+}
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _NCAI_UTILS_H_

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/include/ncai_utils.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/thread_manager.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/thread_manager.h?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/thread_manager.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/thread_manager.h Wed Nov 21 08:29:40 2007
@@ -33,6 +33,7 @@
 
 struct jvmti_frame_pop_listener;
 struct JVMTISingleStepState;
+struct NCAISingleStepState;
 struct ClassLoader;
 struct Registers;
 
@@ -110,6 +111,15 @@
     struct jvmti_frame_pop_listener *frame_pop_listener;
     struct JVMTISingleStepState *ss_state;
     struct Registers *jvmti_saved_exception_registers;
+
+    // Flag and restart address for memory access violation detection
+    int                               violation_flag;
+    void*                             violation_restart_address;
+
+    // Storage for NCAI Single Step data
+    struct NCAISingleStepState* ncai_ss;
+    // Is set when current thread is in NCAI handler
+    jboolean flag_ncai_handler;
 };
 
 struct VM_thread

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Environment.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Environment.cpp?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Environment.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Environment.cpp Wed Nov 21 08:29:40 2007
@@ -212,6 +212,7 @@
     vm_state = VM_INITIALIZING;
 
     TI = new DebugUtilsTI; 
+    NCAI = new GlobalNCAI;
     vm_methods = new Method_Lookup_Table;
 
     nsoTable = nso_init_lookup_table(&string_pool);
@@ -232,6 +233,9 @@
 
     delete TI;
     TI = NULL;
+
+    delete NCAI;
+    NCAI = NULL;
 
     delete vm_methods;
     vm_methods = NULL;

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp Wed Nov 21 08:29:40 2007
@@ -607,6 +607,9 @@
     si_copy_to_registers(si, regs);
 
     if (transfer_control) {
+        // Let NCAI to continue single stepping in exception handler
+        ncai_setup_signal_step(&vmthread->jvmti_thread, (NativeCodePtr)regs->get_ip());
+
         set_exception_object_internal(exn_obj);
         si_transfer_control(si);
         assert(!"si_transfer_control should not return");

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti.cpp?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti.cpp Wed Nov 21 08:29:40 2007
@@ -284,6 +284,9 @@
                                           PRIORITY_SIMPLE_BREAKPOINT,
                                           interpreter_enabled());
 
+    // NCAI interface support
+    newenv->ncai_env = NULL; // GetNCAIEnvironment will allocate ncai_env
+
     LMAutoUnlock lock(&vm->vm_env->TI->TIenvs_lock);
     vm->vm_env->TI->addEnvironment(newenv);
     *env = newenv;

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp Wed Nov 21 08:29:40 2007
@@ -35,6 +35,7 @@
 #include "open/bytecodes.h"
 #include "cci.h"
 
+#include "ncai_internal.h"
 #include "jvmti_break_intf.h"
 #include "cci.h"
 
@@ -132,6 +133,12 @@
     return intf->m_next;
 }
 
+VMBreakPoint*
+VMBreakPoints::get_next_breakpoint(VMBreakPoint* prev)
+{
+    return prev->next;
+}
+
 inline bool
 VMBreakPoints::check_insert_breakpoint(VMBreakPoint* bp)
 {
@@ -210,7 +217,6 @@
 {
     LMAutoUnlock lock(get_lock());
 
-    assert(!interpreter_enabled());
     bool UNREF check = check_insert_breakpoint(bp);
     assert(check);
     if (bp->method != NULL)
@@ -314,7 +320,6 @@
     assert(bp);
     assert(!bp->method || find_breakpoint(bp->method, bp->location));
     assert(bp->method || find_breakpoint(bp->addr));
-    assert(!interpreter_enabled());
 
     LMAutoUnlock lock(get_lock());
     remove_breakpoint(bp);
@@ -571,6 +576,21 @@
 #endif
 }
 
+VMLocalBreak*
+VMBreakPoints::find_thread_local_break(VM_thread* vmthread)
+{
+    assert(vmthread);
+    TRACE2( "jvmti.break", "Find local structure for thread: " << vmthread);
+
+    for (VMLocalBreak* cur = m_local; cur; cur = cur->next)
+    {
+        if (cur->vmthread == vmthread)
+            return cur;
+    }
+
+    return NULL;
+}
+
 void
 VMBreakPoints::process_native_breakpoint()
 {
@@ -627,6 +647,7 @@
         assert(!bp || bp->addr == addr);
         VMLocalBreak local;
         local.priority = priority;
+        local.vmthread = vm_thread;
         while( bp )
         {
             assert(bp->addr == addr);
@@ -644,6 +665,8 @@
                 {
                     local.intf = intf->m_next;
                     VMBreakPoint local_bp = *bp;
+                    local_bp.regs = regs;
+                    local.local_bp = &local_bp;
                     // Set local copy's pointer to local copy of disassembler
                     local_bp.disasm = &idisasm;
                     POINTER_SIZE_INT data = ref->data;
@@ -716,6 +739,7 @@
     switch(type)
     {
     case InstructionDisassembler::UNKNOWN:
+    case InstructionDisassembler::RET:
     {
         char *next_instruction = (char *)interrupted_instruction +
             instruction_length;
@@ -1065,7 +1089,6 @@
 VMBreakInterface::add_reference(NativeCodePtr addr, POINTER_SIZE_INT data)
 {
     assert(addr);
-    assert(!interpreter_enabled());
 
     VMBreakPoints* vm_brpt = VM_Global_State::loader_env->TI->vm_brpt;
     LMAutoUnlock lock(vm_brpt->get_lock());
@@ -1275,9 +1298,12 @@
         assert(bp->disasm);
 
         // code instrumentation
-        jbyte* target_instruction = (jbyte*)bp->addr;
-        bp->saved_byte = *target_instruction;
-        *target_instruction = (jbyte)INSTRUMENTATION_BYTE;
+        if (ncai_read_memory(bp->addr, 1, &bp->saved_byte) != NCAI_ERROR_NONE)
+            return false;
+
+        unsigned char b = (unsigned char)INSTRUMENTATION_BYTE;
+        if (ncai_write_memory(bp->addr, 1, &b) != NCAI_ERROR_NONE)
+            return false;
     }
 
     return true;
@@ -1303,8 +1329,9 @@
             << (bp->method ? method_get_name((Method*)bp->method) : "" )
             << (bp->method ? method_get_descriptor((Method*)bp->method) : "" )
             << " :" << bp->location << " :" << bp->addr);
-        jbyte* target_instruction = (jbyte*)bp->addr;
-        *target_instruction = bp->saved_byte;
+
+        if (ncai_write_memory(bp->addr, 1, &bp->saved_byte) != NCAI_ERROR_NONE)
+            return false;
     }
 
     delete bp->disasm;
@@ -1348,7 +1375,6 @@
 #else
     NativeCodePtr native_location = (NativeCodePtr)regs->get_ip();
 #endif
-    ASSERT_NO_INTERPRETER;
 
     TRACE2("jvmti.break", "BREAKPOINT occured: " << native_location);
 
@@ -1359,6 +1385,38 @@
     // Now it is necessary to set up a transition to
     // process_native_breakpoint_event from the exception/signal handler
     VM_thread *vm_thread = p_TLS_vmthread;
+
+#if 0
+    if (!vm_thread) // FIXME ?????
+    {
+        VMBreakPoints* vm_brpt = ti->vm_brpt;
+        vm_brpt->lock();
+
+        VMBreakPoint* bp;
+        for (unsigned priority = 0; priority < PRIORITY_NUMBER; priority++)
+        {
+            bp = vm_brpt->find_breakpoint(native_location);
+            assert(!bp || bp->addr == native_location);
+
+            while (bp)
+            {
+                VMBreakPoint* next_bp =
+                    vm_brpt->find_next_breakpoint(bp, native_location);
+
+                for (VMBreakInterface* intf = vm_brpt->get_first_intf(priority);
+                     intf; intf = vm_brpt->get_next_intf(intf))
+                {
+                    VMBreakPointRef* ref = intf->find_reference(bp);
+                    if (ref)
+                        intf->remove_reference(ref);
+                }
+                bp = next_bp;
+            }
+        }
+        vm_brpt->unlock();
+    }
+#endif
+
     // Store possibly corrected location
     regs->set_ip((void*)native_location);
     // Copy original registers to TLS

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_dasm.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_dasm.cpp?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_dasm.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_dasm.cpp Wed Nov 21 08:29:40 2007
@@ -191,6 +191,9 @@
             pidi->m_type = INDIRECT_JUMP;
         }
     }
+    else if (inst.mn == Mnemonic_RET) {
+        pidi->m_type = RET;
+    }
     else if (is_jcc(inst.mn)) {
         // relative Jcc is the only possible variant
         assert(pidi->m_argc == 1);
@@ -233,6 +236,14 @@
         // can't happen for INDIRECT_xxx.
         assert(false);
         return NULL;
+#ifdef _IA32_
+    case RET:
+        {
+        const char* sp_value = get_reg_value(DISASM_REG_ESP, pcontext);
+        const char* retAddr = *(char**)sp_value;
+        return (NativeCodePtr)retAddr;
+        }
+#endif // _IA32_
     default:
         // This method should not be called for non-branch instructions.
         assert(false);

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp Wed Nov 21 08:29:40 2007
@@ -42,6 +42,7 @@
 #include "jvmti_break_intf.h"
 #include "stack_iterator.h"
 #include "m2n.h"
+#include "ncai_internal.h"
 
 /*
  * Set Event Callbacks
@@ -844,6 +845,9 @@
     if (!jvmti_should_report_event(JVMTI_EVENT_METHOD_ENTRY))
         return;
 
+    // Report Metod Entry to NCAI
+    ncai_report_method_entry(method);
+
     if (JVMTI_PHASE_LIVE != ti->getPhase())
         return;
 
@@ -1032,6 +1036,9 @@
     DebugUtilsTI *ti = VM_Global_State::loader_env->TI;
     if (!jvmti_should_report_event(JVMTI_EVENT_METHOD_EXIT))
         return;
+
+    // Report Metod Exit to NCAI
+    ncai_report_method_exit(method, was_popped_by_exception, ret_val);
 
     if (JVMTI_PHASE_LIVE != ti->getPhase())
         return;

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_extension.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_extension.cpp?rev=597138&r1=597137&r2=597138&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_extension.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_extension.cpp Wed Nov 21 08:29:40 2007
@@ -34,9 +34,45 @@
     jvmtiExtensionFunctionInfo info;
 };
 
-static JvmtiExtension *jvmti_extension_list = NULL;
+static jvmtiParamInfo jvmtiGetNCAIEnvironmentParams[] =
+{
+    {
+        "ncai_env_ptr",
+        JVMTI_KIND_OUT,
+        JVMTI_TYPE_CVOID,
+        JNI_FALSE
+    },
+    {
+        "version",
+        JVMTI_KIND_IN,
+        JVMTI_TYPE_JINT,
+        JNI_FALSE
+    }
+};
 
-static const jint extensions_number = 0;
+static jvmtiError jvmtiGetNCAIEnvironmentErrors[] =
+{ // Universal errors are excluded according to specification
+    JVMTI_ERROR_NONE,
+};
+
+static JvmtiExtension jvmti_extension_list[] =
+{
+    {
+        NULL,
+        {
+            jvmtiGetNCAIEnvironment,
+            "org.apache.harmony.vm.GetExtensionEnv",
+            "Returns the reference to the NCAI function table",
+            sizeof(jvmtiGetNCAIEnvironmentParams) / sizeof(jvmtiParamInfo),
+            jvmtiGetNCAIEnvironmentParams,
+            sizeof(jvmtiGetNCAIEnvironmentErrors) / sizeof(jvmtiError),
+            jvmtiGetNCAIEnvironmentErrors
+        }
+    }
+
+};
+
+static const jint extensions_number = sizeof(jvmti_extension_list) / sizeof(JvmtiExtension);
 
 static void free_allocated_extension_array(jvmtiExtensionFunctionInfo *array,
                                            jint number)



Mime
View raw message