You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ib...@apache.org on 2008/05/26 02:33:07 UTC

svn commit: r660062 [2/2] - in /harmony/enhanced/drlvm/trunk: make/vm/ vm/include/open/ vm/port/build/ vm/port/include/ vm/port/src/crash_handler/ vm/port/src/memaccess/linux/ vm/port/src/signals/ vm/port/src/signals/include/ vm/port/src/signals/linux/...

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_os.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_os.c?rev=660062&r1=660061&r2=660062&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_os.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_os.c Sun May 25 17:33:06 2008
@@ -17,56 +17,45 @@
 
 #define  _GNU_SOURCE
 #include <assert.h>
-#include <sched.h>		// sched_param
+#include <sched.h>        // sched_param
 #include <semaphore.h>
+#include <signal.h>
 #include <unistd.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
+#include <sys/mman.h>
 #include <stdlib.h>
-#include "port_thread.h"
-
 
+#include "port_malloc.h"
+#include "port_thread.h"
+#include "port_thread_internal.h"
 
-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 */
-    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;
+// Linux/FreeBSD defines
+#if defined(FREEBSD)
+#define STACK_MMAP_ATTRS \
+    (MAP_FIXED | MAP_PRIVATE | MAP_ANON | MAP_STACK)
+#else
+#ifdef _IPF_
+#define STACK_MMAP_ATTRS \
+    (MAP_PRIVATE | MAP_ANONYMOUS)
+#else /* !_IPF_ */
+#define STACK_MMAP_ATTRS \
+    (MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN)
+#endif /* _IPF_ */
+#endif
+
+#ifdef _IPF_
+#define STACK_MAPPING_ACCESS (PROT_READ | PROT_WRITE)
+#else /* !_IPF_ */
+#define STACK_MAPPING_ACCESS (PROT_READ | PROT_WRITE | PROT_EXEC)
+#endif /* _IPF_ */
 
 
 /* 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 port_thread_info_t* init_susres_list_item();
+static port_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 port_thread_info_t* suspend_find_thread(osthread_t thread);
 static void sigusr2_handler(int signum, siginfo_t* info, void* context);
 
 
@@ -88,34 +77,506 @@
     }
 }
 
-/**
- * Terminates the os thread.
- */
+typedef void* (PORT_CDECL *pthread_func_t)(void*);
+
+typedef struct
+{
+    port_threadfunc_t   fun;
+    void*               arg;
+    size_t              stack_size;
+} thread_start_struct_t;
+
+static PORT_CDECL int thread_start_func(void* arg)
+{
+    int err, result;
+    port_tls_data_t* tlsdata = NULL;
+    thread_start_struct_t* ptr = (thread_start_struct_t*)arg;
+    port_threadfunc_t fun = ptr->fun;
+    size_t stack_size = ptr->stack_size;
+    arg = ptr->arg;
+    STD_FREE(ptr);
+
+    if (port_shared_data)
+    {
+        tlsdata = (port_tls_data_t*)STD_ALLOCA(sizeof(port_tls_data_t));
+        err = port_thread_attach_local(tlsdata, FALSE, FALSE, stack_size);
+        assert(err == 0);
+    }
+
+    result = fun(arg);
+
+    if (tlsdata)
+        port_thread_detach();
+
+    return result;
+}
+
+int port_thread_create(/* out */osthread_t* phandle, size_t stacksize, int priority,
+        port_threadfunc_t func, void *data)
+{
+    pthread_t thread;
+    pthread_attr_t attr;
+    struct sched_param param;
+    thread_start_struct_t* startstr;
+    int res;
+
+    if (!port_shared_data)
+    {
+        res = init_port_shared_data();
+        /* assert(res); */
+        /* It's OK to have an error here when Port shared library
+           is not available yet; only signals/crash handling will
+           not be available for the thread */
+        /* return res; */
+    }
+
+    if (!func)
+        return EINVAL;
+
+    startstr =
+        (thread_start_struct_t*)STD_MALLOC(sizeof(thread_start_struct_t));
+
+    if (!startstr)
+        return ENOMEM;
+
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+    if (stacksize != 0)
+    {
+        if (stacksize < MINSIGSTKSZ)
+            stacksize = MINSIGSTKSZ;
+
+        if (port_shared_data)
+        {
+            size_t min_stacksize =
+                /* Let's get alt stack size for normal stack and add guard page size */
+                ((2*port_shared_data->guard_stack_size + port_shared_data->guard_page_size)
+                /* Roung up to alt stack size */
+                    + port_shared_data->guard_stack_size - 1) & ~(port_shared_data->guard_stack_size - 1);
+
+            if (stacksize < min_stacksize)
+                stacksize = min_stacksize;
+        }
+
+        res = pthread_attr_setstacksize(&attr, stacksize);
+        if (res)
+        {
+            pthread_attr_destroy(&attr);
+            STD_FREE(startstr);
+            return res;
+        }
+    }
+
+    if (priority)
+    {
+        res = pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
+        if (res == 0)
+        {
+            param.sched_priority = priority;
+            res = pthread_attr_setschedparam(&attr, &param);
+        }
+        /* This does not work anyway on some Linuses
+        if (res != 0)
+        {
+            pthread_attr_destroy(&attr);
+            STD_FREE(startstr);
+            return res;
+        }*/
+    }
+
+    startstr->fun = func;
+    startstr->arg = data;
+    startstr->stack_size = stacksize;
+
+    res = pthread_create(&thread, &attr, (pthread_func_t)thread_start_func, startstr);
+
+    pthread_attr_destroy(&attr);
+
+    if (res == 0)
+    {
+        *phandle = thread;
+        return 0;
+    }
+
+    STD_FREE(startstr);
+    return res;
+}
+
+static int set_guard_page(port_tls_data_t* tlsdata, Boolean set)
+{
+    int res;
+    stack_t sigalt;
+
+    if (!tlsdata)
+        tlsdata = get_private_tls_data();
+
+    if (!tlsdata)
+        return -1;
+
+    if (!tlsdata->guard_page_addr)
+        return 0;
+
+    if ((set && tlsdata->guard_page_set) ||
+         !set && !tlsdata->guard_page_set)
+        return 0; // Already in needed state
+
+    res = mprotect(tlsdata->guard_page_addr, tlsdata->guard_page_size,
+                    set ? PROT_NONE : (PROT_READ | PROT_WRITE | PROT_EXEC));
+
+    if (res != 0)
+        return errno;
+
+    // sets alternative stack
+    sigalt.ss_sp = tlsdata->guard_stack_addr;
+    sigalt.ss_size = tlsdata->guard_stack_size;
+//#if defined(FREEBSD)
+    sigalt.ss_flags = set ? 0 : SS_DISABLE;
+//#else
+//    sigalt.ss_flags = set ? SS_ONSTACK : SS_DISABLE;
+//#endif
+    res = sigaltstack(&sigalt, NULL);
+
+    if (res != 0)
+        return errno;
+
+    tlsdata->guard_page_set = set;
+    return 0;
+}
+
+int port_thread_restore_guard_page()
+{
+    return set_guard_page(NULL, TRUE);
+}
+
+int port_thread_clear_guard_page()
+{
+    return set_guard_page(NULL, FALSE);
+}
+
+void port_thread_postpone_guard_page()
+{
+    port_tls_data_t* tlsdata = get_private_tls_data();
+
+    if (!tlsdata || !tlsdata->guard_page_addr)
+        return;
+
+    tlsdata->restore_guard_page = FALSE;
+}
+
+void* port_thread_get_stack_address()
+{
+    port_tls_data_t* tlsdata = get_private_tls_data();
+    return tlsdata ? tlsdata->stack_addr : NULL;
+}
+
+size_t port_thread_get_stack_size()
+{
+    port_tls_data_t* tlsdata = get_private_tls_data();
+    return tlsdata ? tlsdata->stack_size : 0;
+}
+
+size_t port_thread_get_effective_stack_size()
+{
+    port_tls_data_t* tlsdata = get_private_tls_data();
+
+    if (!tlsdata)
+        return 0;
+
+    if (!tlsdata->guard_page_addr || !tlsdata->guard_page_set)
+        return tlsdata->stack_size
+               - PSD->guard_page_size
+               - PSD->mem_protect_size;
+
+    return tlsdata->stack_size - 2*PSD->guard_page_size
+           - PSD->guard_stack_size - PSD->mem_protect_size;
+}
+
+static int setup_stack(port_tls_data_t* tlsdata)
+{
+    int res;
+    void* ptr;
+    stack_t sigalt;
+    size_t current_page_addr, mapping_addr, mapping_size;
+
+    if (!port_shared_data)
+        return -1;
+
+    current_page_addr = ((size_t)&res) & ~(PSD->guard_page_size - 1);
+    // leave place for mmap work
+    mapping_addr = current_page_addr - PSD->guard_page_size;
+    // found size of the stack area which should be maped
+    mapping_size = tlsdata->stack_size
+            - ((size_t)tlsdata->stack_addr - mapping_addr);
+
+    if ((size_t)(&res) - PSD->mem_protect_size
+            < (size_t)tlsdata->guard_page_addr + tlsdata->guard_page_size)
+        return EINVAL;
+
+    // maps unmapped part of the stack
+    ptr = (char*)mmap(tlsdata->stack_addr - tlsdata->stack_size, mapping_size,
+            STACK_MAPPING_ACCESS, STACK_MMAP_ATTRS, -1, 0);
+
+    if (ptr == MAP_FAILED)
+        return errno;
+
+    res = set_guard_page(tlsdata, TRUE);
+
+    if (res != 0)
+        return errno;
+
+    return 0;
+}
+
+inline int find_stack_addr_size(void** paddr, size_t* psize)
+{
+    int err;
+    pthread_attr_t pthread_attr;
+    void* stack_addr;
+    size_t stack_size;
+    pthread_t thread = pthread_self();
+
+    if (!paddr) return EINVAL;
+
+    err = pthread_attr_init(&pthread_attr);
+    if (err != 0) return err;
+
+#if defined(FREEBSD)
+    err = pthread_attr_get_np(thread, &pthread_attr);
+#else
+    err = pthread_getattr_np(thread, &pthread_attr);
+#endif
+    if (err != 0) return err;
+
+    err = pthread_attr_getstack(&pthread_attr, &stack_addr, &stack_size);
+    if (err != 0) return err;
+
+    pthread_attr_destroy(&pthread_attr);
+    *paddr = (void*)((size_t)stack_addr + stack_size);
+    *psize = stack_size;
+    return 0;
+}
+
+static int init_stack(port_tls_data_t* tlsdata, size_t stack_size, Boolean temp)
+{
+    int err;
+    size_t stack_begin;
+
+    if (!port_shared_data)
+        return -1;
+
+    err = find_stack_addr_size(&tlsdata->stack_addr, &tlsdata->stack_size);
+    if (err != 0) return err;
+
+    if (tlsdata->foreign || temp || stack_size == 0)
+        tlsdata->stack_size = PSD->foreign_stack_size;
+    else
+        tlsdata->stack_size = stack_size;
+
+    tlsdata->guard_page_size = PSD->guard_page_size;
+    tlsdata->guard_stack_size = PSD->guard_stack_size;
+    tlsdata->mem_protect_size = PSD->mem_protect_size;
+
+    if (temp)
+        return 0;
+
+    stack_begin = (size_t)tlsdata->stack_addr - tlsdata->stack_size;
+    tlsdata->guard_stack_addr = (void*)(stack_begin + tlsdata->guard_page_size);
+    tlsdata->guard_page_addr =
+        (void*)((size_t)tlsdata->guard_stack_addr + tlsdata->guard_stack_size);
+
+    return setup_stack(tlsdata);
+}
+
+int port_thread_attach_local(port_tls_data_t* tlsdata, Boolean temp,
+                                    Boolean foreign, size_t stack_size)
+{
+    int res;
+
+    memset(tlsdata, 0, sizeof(port_tls_data_t));
+
+    tlsdata->foreign = foreign;
+    res = init_stack(tlsdata, stack_size, temp);
+    if (res != 0) return res;
+/* They are already zeroed
+    tlsdata->violation_flag = 0;
+    tlsdata->debugger = FALSE;
+    tlsdata->produce_core = FALSE;*/
+
+    res = set_private_tls_data(tlsdata);
+
+    if (res != 0)
+        set_guard_page(tlsdata, FALSE);
+
+    return res;
+}
+
+int port_thread_attach()
+{
+    int res;
+    port_tls_data_t* tlsdata;
+
+    if (!port_shared_data && (res = init_port_shared_data()) != 0)
+        return res;
+
+    if (get_private_tls_data())
+        return 0;
+
+    tlsdata = (port_tls_data_t*)STD_MALLOC(sizeof(port_tls_data_t));
+
+    if (!tlsdata)
+        return ENOMEM;
+
+    res = port_thread_attach_local(tlsdata, FALSE, TRUE, 0);
+
+    if (res != 0)
+        STD_FREE(tlsdata);
+
+    return res;
+}
+
+int port_thread_detach_temporary()
+{
+    port_tls_data_t* tlsdata = get_private_tls_data();
+
+    if (!tlsdata || tlsdata->guard_page_addr)
+        return -1;
+
+    return set_private_tls_data(NULL);
+}
+
+int port_thread_detach()
+{
+    port_tls_data_t* tlsdata;
+    int res;
+
+    if (!port_shared_data && (res = init_port_shared_data()) != 0)
+        return res;
+
+    tlsdata = get_private_tls_data();
+
+    if (!tlsdata)
+        return 0;
+
+    if (port_thread_detach_temporary() == 0)
+        return 0;
+
+    res = set_guard_page(tlsdata, FALSE);
+
+    if (res != 0)
+        return res;
+
+    if (tlsdata->foreign)
+        STD_FREE(tlsdata);
+
+    return set_private_tls_data(NULL);
+}
+
+int port_thread_set_priority(osthread_t os_thread, int priority)
+{
+#if defined(FREEBSD)
+    /* Not sure why we don't just use this on linux? - MRH */
+    struct sched_param param;
+    int policy;
+    int r = pthread_getschedparam(os_thread, &policy, &param);
+    if (r == 0) {
+        param.sched_priority = priority;
+        r = pthread_setschedparam(os_thread, policy, &param);
+    }
+    return r;
+#else
+    // setting thread priority on linux is only supported for current thread
+    if (os_thread == pthread_self()) {
+        int r;
+        struct sched_param param;
+        pid_t self = gettid();
+        param.sched_priority = priority;
+        r = sched_setparam(self, &param);
+        return r ? errno : 0;
+    } else {
+        // setting other thread priority not supported on linux
+        return 0;
+    }
+#endif
+}
+
+osthread_t port_thread_current()
+{
+    return pthread_self();
+}
+
+int port_thread_free_handle(osthread_t os_thread)
+{
+    return 0;
+}
+
+int port_thread_join(osthread_t os_thread)
+{
+    int error;
+
+    do {
+        // FIXME - somehow pthread_join returns before thread is terminated
+        error = pthread_join(os_thread, NULL);
+    } while (error != ESRCH && error != EINVAL && error != EDEADLK);
+    return 0;
+}
+
 int port_thread_cancel(osthread_t os_thread)
 {
     int status;
-    os_thread_info_t* pinfo;
+    port_thread_info_t* pinfo;
 
     if (!suspend_init_lock())
         return -1;
 
     pinfo = suspend_find_thread(os_thread);
+
+    if (os_thread == pthread_self())
+    {
+        if (pinfo && status == 0)
+            suspend_remove_thread(os_thread);
+        pthread_mutex_unlock(&PSD->suspend_mutex);
+        return pthread_cancel(os_thread);
+    }
+
     status = pthread_cancel(os_thread);
 
     if (pinfo && status == 0)
         suspend_remove_thread(os_thread);
 
-    pthread_mutex_unlock(&g_suspend_mutex);
+    pthread_mutex_unlock(&PSD->suspend_mutex);
     return status;
 }
 
-/**
-* Sends a signal to a thread to make sure thread's write
- * buffers are flushed.
- */
+void port_thread_exit(int status)
+{
+    pthread_exit((void*)(size_t)status);
+}
+
+int port_get_thread_times(osthread_t os_thread, int64* pkernel, int64* puser)
+{
+    clockid_t clock_id;
+    struct timespec tp;
+    int r;
+#ifdef FREEBSD
+    return EINVAL; /* TOFIX: Implement */
+#else
+
+    r = pthread_getcpuclockid(os_thread, &clock_id);
+    if (r) return r;
+
+    r = clock_gettime(clock_id, &tp);
+    if (r) return r;
+
+    *puser = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
+    return 0;
+#endif
+}
+
 void port_thread_yield_other(osthread_t os_thread) {
     struct timespec timeout;
-    os_thread_info_t* pinfo;
+    port_thread_info_t* pinfo;
+    int err = -1;
 
     if (!suspend_init_lock())
         return;
@@ -123,37 +584,35 @@
     pinfo = suspend_find_thread(os_thread);
 
     if (pinfo && pinfo->suspend_count > 0) {
-        pthread_mutex_unlock(&g_suspend_mutex);
+        pthread_mutex_unlock(&PSD->suspend_mutex);
         return;
     }
 
-    g_suspendee = os_thread;
-    g_req_type = THREADREQ_YIELD;
+    PSD->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);
+        get_exceed_time(&timeout, 10000000L);
+        err = sem_timedwait(&PSD->yield_sem, &timeout);
+//        sem_wait(&PSD->yield_sem);
     } else {
         if (pinfo)
             suspend_remove_thread(os_thread);
     }
 
-    g_req_type = THREADREQ_NONE;
-    pthread_mutex_unlock(&g_suspend_mutex);
+    if (err != 0)
+        PSD->req_type = THREADREQ_NONE;
+
+    pthread_mutex_unlock(&PSD->suspend_mutex);
 }
 
 
-/**
- * Suspend given thread
- * @param thread The thread to suspend
- */
 int port_thread_suspend(osthread_t thread)
 {
     int status;
-    os_thread_info_t* pinfo;
+    port_thread_info_t* pinfo;
 
     if (!thread)
         return -1;
@@ -168,24 +627,24 @@
 
     if (!pinfo)
     {
-        pthread_mutex_unlock(&g_suspend_mutex);
+        pthread_mutex_unlock(&PSD->suspend_mutex);
         return -1;
     }
 
     if (pinfo->suspend_count > 0)
     {
         ++pinfo->suspend_count;
-        pthread_mutex_unlock(&g_suspend_mutex);
+        pthread_mutex_unlock(&PSD->suspend_mutex);
         return 0;
     }
 
-    g_suspendee = thread;
-    g_req_type = THREADREQ_SUS;
+    PSD->suspendee = thread;
+    PSD->req_type = THREADREQ_SUS;
 
     if (pthread_kill(thread, SIGUSR2) != 0)
     {
         suspend_remove_thread(thread);
-        pthread_mutex_unlock(&g_suspend_mutex);
+        pthread_mutex_unlock(&PSD->suspend_mutex);
         return -1;
     }
 
@@ -194,18 +653,14 @@
     /* Check result */
     status = (pinfo->suspend_count > 0) ? 0 : -1;
 
-    pthread_mutex_unlock(&g_suspend_mutex);
+    pthread_mutex_unlock(&PSD->suspend_mutex);
     return status;
 }
 
-/**
- * Resume given thread
- * @param thread The thread to resume
- */
 int port_thread_resume(osthread_t thread)
 {
     int status;
-    os_thread_info_t* pinfo;
+    port_thread_info_t* pinfo;
 
     if (!thread)
         return -1;
@@ -217,24 +672,24 @@
 
     if (!pinfo)
     {
-        pthread_mutex_unlock(&g_suspend_mutex);
+        pthread_mutex_unlock(&PSD->suspend_mutex);
         return -1;
     }
 
     if (pinfo->suspend_count > 1)
     {
         --pinfo->suspend_count;
-        pthread_mutex_unlock(&g_suspend_mutex);
+        pthread_mutex_unlock(&PSD->suspend_mutex);
         return 0;
     }
 
-    g_suspendee = thread;
-    g_req_type = THREADREQ_RES;
+    PSD->suspendee = thread;
+    PSD->req_type = THREADREQ_RES;
 
     if ((status = pthread_kill(thread, SIGUSR2)) != 0)
     {
         suspend_remove_thread(thread);
-        pthread_mutex_unlock(&g_suspend_mutex);
+        pthread_mutex_unlock(&PSD->suspend_mutex);
         return status;
     }
 
@@ -243,18 +698,13 @@
 
     suspend_remove_thread(thread);
 
-    pthread_mutex_unlock(&g_suspend_mutex);
+    pthread_mutex_unlock(&PSD->suspend_mutex);
     return 0;
 }
 
-/**
- * Determine suspend count for the given thread
- * @param thread The thread to check
- * @return -1 if error have occured
- */
 int port_thread_get_suspend_count(osthread_t thread)
 {
-    os_thread_info_t* pinfo;
+    port_thread_info_t* pinfo;
     int suspend_count;
 
     if (!thread)
@@ -267,20 +717,14 @@
 
     suspend_count = pinfo ? pinfo->suspend_count : 0;
 
-    pthread_mutex_unlock(&g_suspend_mutex);
+    pthread_mutex_unlock(&PSD->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 port_thread_get_context(osthread_t thread, thread_context_t *context)
 {
     int status = -1;
-    os_thread_info_t* pinfo;
+    port_thread_info_t* pinfo;
 
     if (!thread || !context)
         return -1;
@@ -292,7 +736,7 @@
 
     if (!pinfo)
     {
-        pthread_mutex_unlock(&g_suspend_mutex);
+        pthread_mutex_unlock(&PSD->suspend_mutex);
         return status;
     }
 
@@ -302,20 +746,14 @@
         status = -1;
     }
 
-    pthread_mutex_unlock(&g_suspend_mutex);
+    pthread_mutex_unlock(&PSD->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 port_thread_set_context(osthread_t thread, thread_context_t *context)
 {
     int status = -1;
-    os_thread_info_t* pinfo;
+    port_thread_info_t* pinfo;
 
     if (!thread || !context)
         return -1;
@@ -327,7 +765,7 @@
 
     if (!pinfo)
     {
-        pthread_mutex_unlock(&g_suspend_mutex);
+        pthread_mutex_unlock(&PSD->suspend_mutex);
         return status;
     }
 
@@ -337,53 +775,39 @@
         status = 0;
     }
 
-    pthread_mutex_unlock(&g_suspend_mutex);
+    pthread_mutex_unlock(&PSD->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;
+    int result = 1;
 
-    if (initialized)
+    if (port_shared_data && PSD->signal_set)
         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);
+    if (!port_shared_data && init_port_shared_data() != 0)
+        return 0;
 
-        g_suspended_list = NULL;
-        g_req_type = THREADREQ_NONE;
+    pthread_mutex_lock(&PSD->suspend_init_mutex);
 
+    if (!PSD->signal_set)
+    {
         /* 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;
+        if (sigaction(SIGUSR2, &sa, NULL) != 0)
+            result = 0;
+        else
+            PSD->signal_set = TRUE;
     }
 
-    pthread_mutex_unlock(&suspend_init_mutex);
-    return 1;
+    pthread_mutex_unlock(&PSD->suspend_init_mutex);
+    return result;
 }
 
 static int suspend_init_lock()
@@ -391,16 +815,16 @@
     if (!suspend_init())
         return 0;
 
-    if (pthread_mutex_lock(&g_suspend_mutex) != 0)
+    if (pthread_mutex_lock(&PSD->suspend_mutex) != 0)
         return 0;
 
     return 1;
 }
 
-static os_thread_info_t* init_susres_list_item()
+static port_thread_info_t* init_susres_list_item()
 {
-    os_thread_info_t* pinfo =
-        (os_thread_info_t*)malloc(sizeof(os_thread_info_t));
+    port_thread_info_t* pinfo =
+        (port_thread_info_t*)malloc(sizeof(port_thread_info_t));
 
     if (pinfo == NULL)
         return NULL;
@@ -418,25 +842,25 @@
     return pinfo;
 }
 
-static os_thread_info_t* suspend_add_thread(osthread_t thread)
+static port_thread_info_t* suspend_add_thread(osthread_t thread)
 {
-    os_thread_info_t* pinfo = init_susres_list_item();
+    port_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;
+    pinfo->next = PSD->suspended_list;
+    PSD->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;
+    port_thread_info_t** pprev = &PSD->suspended_list;
+    port_thread_info_t* pinfo;
 
-    for (pinfo = g_suspended_list; pinfo; pinfo = pinfo->next)
+    for (pinfo = PSD->suspended_list; pinfo; pinfo = pinfo->next)
     {
         if (pinfo->thread == thread)
             break;
@@ -452,12 +876,12 @@
     }
 }
 
-static os_thread_info_t* suspend_find_thread(osthread_t thread)
+static port_thread_info_t* suspend_find_thread(osthread_t thread)
 {
-    os_thread_info_t* pinfo;
+    port_thread_info_t* pinfo;
     int status;
 
-    for (pinfo = g_suspended_list; pinfo; pinfo = pinfo->next)
+    for (pinfo = PSD->suspended_list; pinfo; pinfo = pinfo->next)
     {
         if (pinfo->thread == thread)
             break;
@@ -470,31 +894,34 @@
 static void sigusr2_handler(int signum, siginfo_t* info, void* context)
 {
     int status;
-    os_thread_info_t* pinfo;
+    port_thread_info_t* pinfo;
 
-    if (!suspend_init())
+    if (!PSD)
         return;
 
-    if (signum != SIGUSR2)
-        return;
-
-    /* We have g_suspend_mutex locked already */
+    /* We have suspend_mutex locked already */
 
-    if (g_req_type == THREADREQ_YIELD)
+    if (PSD->req_type == THREADREQ_YIELD)
     {
-        g_req_type = THREADREQ_NONE;
+        PSD->req_type = THREADREQ_NONE;
         /* Inform requester */
-        sem_post(&g_yield_sem);
+        sem_post(&PSD->yield_sem);
         return;
     }
 
-    if ((pinfo = suspend_find_thread(g_suspendee)) == NULL)
+    if (PSD->req_type == THREADREQ_NONE)
         return;
 
-    if (g_req_type == THREADREQ_SUS)
+    if (!suspend_init() ||
+        (pinfo = suspend_find_thread(PSD->suspendee)) == NULL)
+    {
+        return; /* Return to interrupted THREADREQ_SUS handler */
+    }
+
+    if (PSD->req_type == THREADREQ_SUS)
     {
         pinfo->suspend_count++;
-        g_req_type = THREADREQ_NONE;
+        PSD->req_type = THREADREQ_NONE;
         memcpy(&pinfo->context, context, sizeof(ucontext_t));
         /* Inform suspender */
         sem_post(&pinfo->wake_sem);
@@ -513,10 +940,10 @@
         sem_post(&pinfo->wake_sem);
         return;
     }
-    else if (g_req_type == THREADREQ_RES)
+    else if (PSD->req_type == THREADREQ_RES)
     {
         pinfo->suspend_count--;
-        g_req_type = THREADREQ_NONE;
+        PSD->req_type = THREADREQ_NONE;
         return; /* Return to interrupted THREADREQ_SUS handler */
     }
 }

Added: harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/port_thread_tls_find.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/port_thread_tls_find.c?rev=660062&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/port_thread_tls_find.c (added)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/port_thread_tls_find.c Sun May 25 17:33:06 2008
@@ -0,0 +1,49 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include "open/hythread_ext.h" // To properly include 'windows.h'
+#include "port_thread_internal.h"
+
+
+#define SHPORT_DLL_NAME (CH_SHLIB_NAME ".dll")
+
+volatile port_shared_data_t* port_shared_data = NULL;
+
+typedef int (*fn_port_init_shared_data_t)(volatile port_shared_data_t** pdata);
+
+
+int init_port_shared_data()
+{
+    HMODULE native_handle;
+    fn_port_init_shared_data_t fn_ptr;
+
+    if (port_shared_data)
+        return 0;
+
+    native_handle = LoadLibrary(SHPORT_DLL_NAME);
+
+    if (native_handle == NULL)
+        return -1;
+
+    fn_ptr =
+        (fn_port_init_shared_data_t)GetProcAddress(native_handle, "port_init_shared_data");
+
+    if (!fn_ptr)
+        return -1;
+
+    return fn_ptr(&port_shared_data);
+}

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

Added: harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/port_thread_tls_os.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/port_thread_tls_os.c?rev=660062&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/port_thread_tls_os.c (added)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/port_thread_tls_os.c Sun May 25 17:33:06 2008
@@ -0,0 +1,110 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+
+#include "open/platform_types.h"
+#include "open/hythread_ext.h"
+#include "port_mutex.h"
+#include "port_thread_internal.h"
+
+
+volatile port_shared_data_t* port_shared_data = NULL;
+
+static port_shared_data_t* g_port_shared_data = NULL;
+static port_shared_data_t g_port_shared_data_struct;
+
+
+#define MEM_PROTECT_SIZE 0x100
+
+#ifdef _EM64T_
+#define GUARD_STACK_SIZE (64*1024)
+#else /* IA-32 */
+#define GUARD_STACK_SIZE (find_guard_page_size())
+#endif
+
+
+static size_t find_guard_page_size()
+{
+    SYSTEM_INFO system_info;
+    GetSystemInfo(&system_info);
+    return system_info.dwPageSize;
+}
+
+static int init_psd_structure(port_shared_data_t* data)
+{
+    DWORD key;
+
+    if ((key = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+        return -1;
+
+    data->tls_key = key;
+    InitializeCriticalSection(&data->crit_section);
+    data->foreign_stack_size = 0;
+    data->guard_page_size = find_guard_page_size();
+    data->guard_stack_size = GUARD_STACK_SIZE;
+    data->mem_protect_size = MEM_PROTECT_SIZE;
+    return 0;
+}
+
+__declspec(dllexport) int port_init_shared_data(volatile port_shared_data_t** p_psd)
+{
+    int err = 0;
+static CRITICAL_SECTION struct_lock;
+static int lock_initialized = 0;
+
+    if (*p_psd)
+        return 0;
+
+    if (lock_initialized == 0)
+    { /* Probable race condition because of using static flag */
+        InitializeCriticalSection(&struct_lock);
+        lock_initialized = 1;
+    }
+
+    EnterCriticalSection(&struct_lock);
+
+    /* If another thread had filled the pointer */
+    if (*p_psd)
+    {
+        LeaveCriticalSection(&struct_lock);
+        return 0;
+    }
+
+    /* If structure is already initialized */
+    if (!g_port_shared_data)
+    {
+        err = init_psd_structure(&g_port_shared_data_struct);
+
+        if (err == 0)
+            g_port_shared_data = &g_port_shared_data_struct;
+    }
+
+    if (g_port_shared_data)
+        *p_psd = g_port_shared_data;
+
+    LeaveCriticalSection(&struct_lock);
+    return err;
+}
+
+
+int init_port_shared_data()
+{
+    if (port_shared_data)
+        return 0;
+
+    return port_init_shared_data(&port_shared_data);
+}

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

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_os.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_os.c?rev=660062&r1=660061&r2=660062&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_os.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_os.c Sun May 25 17:33:06 2008
@@ -16,39 +16,393 @@
  */
 
 
-#include <port_atomic.h>
+#include "port_atomic.h"
+#include "port_malloc.h"
 #include "port_thread.h"
+#include "port_thread_internal.h"
 
 
-typedef struct os_thread_info_t os_thread_info_t;
+/* Forward declarations */
+static int suspend_init_lock();
+static port_thread_info_t* init_susres_list_item();
+static port_thread_info_t* suspend_add_thread(osthread_t thread);
+static void suspend_remove_thread(osthread_t thread);
+static port_thread_info_t* suspend_find_thread(osthread_t thread);
 
-struct os_thread_info_t
+
+typedef unsigned (__stdcall *beginthread_func_t)(void*);
+
+typedef struct
 {
-    osthread_t              thread;
-    int                     suspend_count;
-    thread_context_t        context;
+    port_threadfunc_t   fun;
+    void*               arg;
+    size_t              stack_size;
+} thread_start_struct_t;
 
-    os_thread_info_t*       next;
-};
+static unsigned __stdcall thread_start_func(void* arg)
+{
+    int err, result;
+    port_tls_data_t* tlsdata;
+    thread_start_struct_t* ptr = (thread_start_struct_t*)arg;
+    port_threadfunc_t fun = ptr->fun;
+    size_t stack_size = ptr->stack_size;
+    arg = ptr->arg;
+    STD_FREE(ptr);
 
+    if (port_shared_data)
+    {
+        tlsdata = (port_tls_data_t*)STD_ALLOCA(sizeof(port_tls_data_t));
+        err = port_thread_attach_local(tlsdata, FALSE, FALSE, stack_size);
+        assert(err == 0);
+    }
 
-static CRITICAL_SECTION g_crit_section;
-static os_thread_info_t* g_suspended_list = NULL;
+    result = (int)fun(arg);
 
-/* 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);
+    port_thread_detach();
 
+    return result;
+}
+
+
+int port_thread_create(/* out */osthread_t* phandle, size_t stacksize, int priority,
+        port_threadfunc_t func, void *data)
+{
+    uintptr_t handle;
+    thread_start_struct_t* startstr;
+    int res;
+
+    if (!port_shared_data)
+    {
+        res = init_port_shared_data();
+        /* assert(res); */
+        /* It's OK to have an error here when Port shared library
+           is not available yet; only signals/crash handling will
+           not be available for the thread */
+        /* return res; */
+    }
+
+    if (!func)
+        return -1;
+
+    startstr =
+        (thread_start_struct_t*)STD_MALLOC(sizeof(thread_start_struct_t));
+
+    if (!startstr)
+        return -1;
+
+    if (stacksize != 0)
+    {
+        if (port_shared_data)
+        {
+            size_t min_stacksize =
+                /* Let's get alt stack size for normal stack and add guard page size */
+                ((2*port_shared_data->guard_stack_size + port_shared_data->guard_page_size)
+                /* Roung up to alt stack size */
+                    + port_shared_data->guard_stack_size - 1) & ~(port_shared_data->guard_stack_size - 1);
+
+            if (stacksize < min_stacksize)
+                stacksize = min_stacksize;
+        }
+    }
+
+    startstr->fun = func;
+    startstr->arg = data;
+    startstr->stack_size = stacksize;
+
+    handle = _beginthreadex(NULL, stacksize, thread_start_func, startstr, STACK_SIZE_PARAM_IS_A_RESERVATION, NULL);
+
+    if (handle != (uintptr_t)-1L)
+    {
+        *phandle = (HANDLE)handle;
+
+        if (priority)
+            SetThreadPriority(*phandle, priority);
+
+        return 0;
+    }
+
+    STD_FREE(startstr);
+    return res;
+}
+
+static int set_guard_page(port_tls_data_t* tlsdata, Boolean set)
+{
+    if (!tlsdata)
+        tlsdata = get_private_tls_data();
+
+    if (!tlsdata)
+        return -1;
+
+    if (!tlsdata->guard_page_addr)
+        return 0;
+
+    if ((set && tlsdata->guard_page_set) ||
+         !set && !tlsdata->guard_page_set)
+        return 0; // Already in needed state
+
+    if (set)
+    {
+        if ((size_t)&set - PSD->mem_protect_size
+                < (size_t)tlsdata->guard_page_addr + tlsdata->guard_page_size)
+            return -1;
+
+        if (!VirtualAlloc(tlsdata->guard_page_addr, tlsdata->guard_page_size,
+                            MEM_COMMIT, PAGE_GUARD | PAGE_READWRITE))
+            // should be successful always
+            return -1;
+    }
+    else
+    {
+        DWORD oldProtect;
+
+        if ((size_t)&set < (size_t)tlsdata->guard_page_addr + tlsdata->guard_page_size)
+            return -1;
+
+        if (!VirtualProtect(tlsdata->guard_page_addr, tlsdata->guard_page_size,
+                            PAGE_READWRITE, &oldProtect))
+            // should be successful always
+            return -1;
+    }
+
+    tlsdata->guard_page_set = set;
+    return 0;
+}
+
+int port_thread_restore_guard_page()
+{
+    return set_guard_page(NULL, TRUE);
+}
+
+int port_thread_clear_guard_page()
+{
+    return set_guard_page(NULL, FALSE);
+}
+
+void port_thread_postpone_guard_page()
+{
+    port_tls_data_t* tlsdata = get_private_tls_data();
+
+    if (!tlsdata || !tlsdata->guard_page_addr)
+        return;
+
+    tlsdata->restore_guard_page = FALSE;
+}
+
+void* port_thread_get_stack_address()
+{
+    port_tls_data_t* tlsdata = get_private_tls_data();
+    return tlsdata ? tlsdata->stack_addr : NULL;
+}
+
+size_t port_thread_get_stack_size()
+{
+    port_tls_data_t* tlsdata = get_private_tls_data();
+    return tlsdata ? tlsdata->stack_size : 0;
+}
+
+size_t port_thread_get_effective_stack_size()
+{
+    port_tls_data_t* tlsdata = get_private_tls_data();
+
+    if (!tlsdata)
+        return 0;
+
+    if (!tlsdata->guard_page_addr || !tlsdata->guard_page_set)
+        return tlsdata->stack_size
+               - PSD->guard_page_size - PSD->mem_protect_size;
+
+    return tlsdata->stack_size - 2*PSD->guard_page_size
+           - PSD->guard_stack_size - PSD->mem_protect_size;
+}
+
+static int setup_stack(port_tls_data_t* tlsdata)
+{
+#ifdef _EM64T_
+    ULONG guard_stack_size_param;
+#endif
+
+    if (!port_shared_data)
+        return -1;
+
+#ifdef _EM64T_
+    /* this code in future should be used on both platforms x86-32 and x86-64 */
+    guard_stack_size_param = (ULONG)PSD->guard_stack_size;
+
+    if (!SetThreadStackGuarantee(&guard_stack_size_param))
+        /* should be successful always */
+        return -1;
+#endif
+
+    if ((size_t)&tlsdata - PSD->mem_protect_size
+            < (size_t)tlsdata->guard_page_addr + tlsdata->guard_page_size)
+        return -1;
+
+    if (!VirtualFree(tlsdata->guard_stack_addr,
+                        tlsdata->guard_stack_size, MEM_DECOMMIT))
+        // should be successful always
+        return -1;
+
+    return 0;
+}
+
+static int find_stack_addr_size(void** paddr, size_t* psize)
+{
+    size_t reg_size;
+    MEMORY_BASIC_INFORMATION memory_information;
+
+    VirtualQuery(&memory_information, &memory_information, sizeof(memory_information));
+    reg_size = memory_information.RegionSize;
+    *paddr = (void*)((size_t)memory_information.BaseAddress + reg_size);
+    *psize = (size_t)*paddr - (size_t)memory_information.AllocationBase;
+    return 0;
+}
+
+static int init_stack(port_tls_data_t* tlsdata, size_t stack_size, Boolean temp)
+{
+    int err;
+    size_t stack_begin;
+
+    if (!port_shared_data)
+        return -1;
+
+    err = find_stack_addr_size(&tlsdata->stack_addr, &tlsdata->stack_size);
+    if (err != 0) return err;
+
+    if (stack_size)
+        tlsdata->stack_size = stack_size;
+
+    tlsdata->guard_page_size = PSD->guard_page_size;
+    tlsdata->guard_stack_size = PSD->guard_stack_size;
+    tlsdata->mem_protect_size = PSD->mem_protect_size;
+
+    if (temp)
+        return 0;
+
+    stack_begin = (size_t)tlsdata->stack_addr - tlsdata->stack_size;
+    tlsdata->guard_stack_addr = (void*)(stack_begin + tlsdata->guard_page_size);
+    tlsdata->guard_page_addr =
+        (void*)((size_t)tlsdata->guard_stack_addr + tlsdata->guard_stack_size);
+
+    return setup_stack(tlsdata);
+}
+
+int port_thread_attach_local(port_tls_data_t* tlsdata, Boolean temp,
+                                    Boolean foreign, size_t stack_size)
+{
+    int res;
+
+    memset(tlsdata, 0, sizeof(port_tls_data_t));
+
+    tlsdata->foreign = foreign;
+    res = init_stack(tlsdata, stack_size, temp);
+    if (res != 0) return res;
+
+    res = set_private_tls_data(tlsdata);
+
+    if (res != 0)
+        set_guard_page(tlsdata, FALSE);
+
+    return res;
+}
+
+int port_thread_attach()
+{
+    int res;
+    port_tls_data_t* tlsdata;
+
+    if (!port_shared_data && (res = init_port_shared_data()) != 0)
+        return res;
+
+    if (get_private_tls_data())
+        return 0;
+
+    tlsdata = (port_tls_data_t*)STD_MALLOC(sizeof(port_tls_data_t));
+
+    if (!tlsdata) return ENOMEM;
+
+    res = port_thread_attach_local(tlsdata, FALSE, TRUE, 0);
+
+    if (res != 0)
+        STD_FREE(tlsdata);
+
+    return res;
+}
+
+int port_thread_detach_temporary()
+{
+    port_tls_data_t* tlsdata = get_private_tls_data();
+
+    if (!tlsdata || tlsdata->guard_page_addr)
+        return -1;
+
+    return set_private_tls_data(NULL);
+}
+
+int port_thread_detach()
+{
+    port_tls_data_t* tlsdata;
+    int res;
+
+    if (!port_shared_data && (res = init_port_shared_data()) != 0)
+        return res;
+
+    tlsdata = get_private_tls_data();
+
+    if (!tlsdata)
+        return 0;
+
+    if (port_thread_detach_temporary() == 0)
+        return 0;
+
+    if (tlsdata->foreign)
+        STD_FREE(tlsdata);
+
+    return set_private_tls_data(NULL);
+}
+
+int port_thread_set_priority(osthread_t os_thread, int priority)
+{
+    if (SetThreadPriority(os_thread, (int)priority)) {
+        return 0;
+    } else {
+        return GetLastError();
+    }
+}
+
+osthread_t port_thread_current()
+{
+    HANDLE hproc = GetCurrentProcess();
+    HANDLE hthread = GetCurrentThread();
+    if (!DuplicateHandle(hproc, hthread,
+                         hproc, &hthread, 0, FALSE,
+                         DUPLICATE_SAME_ACCESS)) {
+        return NULL;
+    }
+    return hthread;
+}
+
+int port_thread_free_handle(osthread_t os_thread)
+{
+    BOOL r = CloseHandle(os_thread);
+    return !r;
+}
+
+int port_thread_join(osthread_t os_thread)
+{
+    int error = 0;
+    DWORD r;
+    r = WaitForSingleObject(os_thread, INFINITE);
+    if (r == WAIT_OBJECT_0 || r == WAIT_ABANDONED)
+        r = 0;
+    else
+        r = GetLastError();
+    CloseHandle(os_thread);
+    return r;
+}
 
-/**
- * Terminates the os thread.
- */
 int port_thread_cancel(osthread_t os_thread)
 {
-    os_thread_info_t* pinfo;
+    port_thread_info_t* pinfo;
     int status = TM_ERROR_NONE;
 
     if (!suspend_init_lock())
@@ -62,17 +416,42 @@
     if (!TerminateThread(os_thread, 0))
         status = (int)GetLastError();
 
-    LeaveCriticalSection(&g_crit_section);
+    LeaveCriticalSection(&PSD->crit_section);
     return status;
 }
 
-/**
- * Causes the other thread to have a memory barrier by suspending
- * and resuming it.
- */
+void port_thread_exit(int status)
+{
+    ExitThread(status);
+}
+
+int port_get_thread_times(osthread_t os_thread, int64* pkernel, int64* puser)
+{
+    FILETIME creation_time;
+    FILETIME exit_time;
+    FILETIME kernel_time;
+    FILETIME user_time;
+    int r;
+
+    r = GetThreadTimes(os_thread,
+            &creation_time, &exit_time, &kernel_time, &user_time);
+
+    if (r) {
+        // according to MSDN, time is counted in 100 ns units, so we need to multiply by 100
+        *pkernel = 100 *
+            (((int64)kernel_time.dwHighDateTime << 32)
+             | kernel_time.dwLowDateTime);
+        *puser = 100 *
+            (((int64)user_time.dwHighDateTime << 32)
+             | user_time.dwLowDateTime);
+        return 0;
+    } else
+        return GetLastError();
+}
+
 void port_thread_yield_other(osthread_t os_thread)
 {
-    os_thread_info_t* pinfo;
+    port_thread_info_t* pinfo;
 
     /*
      * Synchronization is needed to avoid cyclic (mutual) suspension problem.
@@ -85,7 +464,7 @@
     pinfo = suspend_find_thread(os_thread);
 
     if (pinfo && pinfo->suspend_count > 0) {
-        LeaveCriticalSection(&g_crit_section);
+        LeaveCriticalSection(&PSD->crit_section);
         return;
     }
 
@@ -94,17 +473,13 @@
         ResumeThread(os_thread);
     }
 
-    LeaveCriticalSection(&g_crit_section);
+    LeaveCriticalSection(&PSD->crit_section);
 }
 
 
-/**
- * Suspend given thread
- * @param thread The thread to suspend
- */
 int port_thread_suspend(osthread_t thread)
 {
-    os_thread_info_t* pinfo;
+    port_thread_info_t* pinfo;
     DWORD old_count;
 
     if (!thread)
@@ -120,14 +495,14 @@
 
     if (!pinfo)
     {
-        LeaveCriticalSection(&g_crit_section);
+        LeaveCriticalSection(&PSD->crit_section);
         return TM_ERROR_OUT_OF_MEMORY;
     }
 
     if (pinfo->suspend_count > 0)
     {
         ++pinfo->suspend_count;
-        LeaveCriticalSection(&g_crit_section);
+        LeaveCriticalSection(&PSD->crit_section);
         return TM_ERROR_NONE;
     }
 
@@ -136,22 +511,18 @@
     if (old_count == (DWORD)-1)
     {
         int status = (int)GetLastError();
-        LeaveCriticalSection(&g_crit_section);
+        LeaveCriticalSection(&PSD->crit_section);
         return status;
     }
 
     ++pinfo->suspend_count;
-    LeaveCriticalSection(&g_crit_section);
+    LeaveCriticalSection(&PSD->crit_section);
     return TM_ERROR_NONE;
 }
 
-/**
- * Resume given thread
- * @param thread The thread to resume
- */
 int port_thread_resume(osthread_t thread)
 {
-    os_thread_info_t* pinfo;
+    port_thread_info_t* pinfo;
     DWORD old_count;
 
     if (!thread)
@@ -164,14 +535,14 @@
 
     if (!pinfo)
     {
-        LeaveCriticalSection(&g_crit_section);
+        LeaveCriticalSection(&PSD->crit_section);
         return TM_ERROR_UNATTACHED_THREAD;
     }
 
     if (pinfo->suspend_count > 1)
     {
         --pinfo->suspend_count;
-        LeaveCriticalSection(&g_crit_section);
+        LeaveCriticalSection(&PSD->crit_section);
         return TM_ERROR_NONE;
     }
 
@@ -180,25 +551,20 @@
     if (old_count == (DWORD)-1)
     {
         int status = (int)GetLastError();
-        LeaveCriticalSection(&g_crit_section);
+        LeaveCriticalSection(&PSD->crit_section);
         return status;
     }
 
     if (--pinfo->suspend_count == 0)
         suspend_remove_thread(thread);
 
-    LeaveCriticalSection(&g_crit_section);
+    LeaveCriticalSection(&PSD->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 port_thread_get_suspend_count(osthread_t thread)
 {
-    os_thread_info_t* pinfo;
+    port_thread_info_t* pinfo;
     int suspend_count;
 
     if (!thread)
@@ -210,19 +576,13 @@
     pinfo = suspend_find_thread(thread);
     suspend_count = pinfo ? pinfo->suspend_count : 0;
 
-    LeaveCriticalSection(&g_crit_section);
+    LeaveCriticalSection(&PSD->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 port_thread_get_context(osthread_t thread, thread_context_t *context)
 {
-    os_thread_info_t* pinfo;
+    port_thread_info_t* pinfo;
     CONTEXT local_context;
 
     if (!thread || !context)
@@ -235,7 +595,7 @@
 
     if (!pinfo)
     {
-        LeaveCriticalSection(&g_crit_section);
+        LeaveCriticalSection(&PSD->crit_section);
         return TM_ERROR_UNATTACHED_THREAD;
     }
 
@@ -248,25 +608,19 @@
     if (!GetThreadContext(thread, &local_context))
     {
         int status = (int)GetLastError();
-        LeaveCriticalSection(&g_crit_section);
+        LeaveCriticalSection(&PSD->crit_section);
         return status;
     }
 
     pinfo->context = local_context;
     *context = local_context;
-    LeaveCriticalSection(&g_crit_section);
+    LeaveCriticalSection(&PSD->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 port_thread_set_context(osthread_t thread, thread_context_t *context)
 {
-    os_thread_info_t* pinfo;
+    port_thread_info_t* pinfo;
 
     if (!thread || !context)
         return -1;
@@ -278,19 +632,19 @@
 
     if (!pinfo)
     {
-        LeaveCriticalSection(&g_crit_section);
+        LeaveCriticalSection(&PSD->crit_section);
         return TM_ERROR_UNATTACHED_THREAD;
     }
 
     if (!SetThreadContext(thread, context))
     {
         int status = (int)GetLastError();
-        LeaveCriticalSection(&g_crit_section);
+        LeaveCriticalSection(&PSD->crit_section);
         return status;
     }
 
     pinfo->context = *context;
-    LeaveCriticalSection(&g_crit_section);
+    LeaveCriticalSection(&PSD->crit_section);
     return TM_ERROR_NONE;
 }
 
@@ -304,17 +658,17 @@
         // Critical section should be initialized only once,
         // do nothing in case someone else already initialized it.
         if (port_atomic_cas16((volatile uint16*)&initialized, 1, 0) == 0)
-            InitializeCriticalSectionAndSpinCount(&g_crit_section, 400);
+            InitializeCriticalSectionAndSpinCount(&PSD->crit_section, 400);
     }
 
-    EnterCriticalSection(&g_crit_section);
+    EnterCriticalSection(&PSD->crit_section);
     return 1;
 }
 
-static os_thread_info_t* init_susres_list_item()
+static port_thread_info_t* init_susres_list_item()
 {
-    os_thread_info_t* pinfo =
-        (os_thread_info_t*)malloc(sizeof(os_thread_info_t));
+    port_thread_info_t* pinfo =
+        (port_thread_info_t*)malloc(sizeof(port_thread_info_t));
 
     if (pinfo)
         pinfo->suspend_count = 0;
@@ -322,26 +676,26 @@
     return pinfo;
 }
 
-static os_thread_info_t* suspend_add_thread(osthread_t thread)
+static port_thread_info_t* suspend_add_thread(osthread_t thread)
 {
-    os_thread_info_t* pinfo = init_susres_list_item();
+    port_thread_info_t* pinfo = init_susres_list_item();
 
     if (!pinfo)
         return NULL;
 
     pinfo->thread = thread;
-    pinfo->next = g_suspended_list;
-    g_suspended_list = pinfo;
+    pinfo->next = PSD->suspended_list;
+    PSD->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;
+    port_thread_info_t** pprev = &PSD->suspended_list;
+    port_thread_info_t* pinfo;
 
-    for (pinfo = g_suspended_list; pinfo; pinfo = pinfo->next)
+    for (pinfo = PSD->suspended_list; pinfo; pinfo = pinfo->next)
     {
         if (pinfo->thread == thread)
             break;
@@ -356,11 +710,11 @@
     }
 }
 
-static os_thread_info_t* suspend_find_thread(osthread_t thread)
+static port_thread_info_t* suspend_find_thread(osthread_t thread)
 {
-    os_thread_info_t* pinfo;
+    port_thread_info_t* pinfo;
 
-    for (pinfo = g_suspended_list; pinfo; pinfo = pinfo->next)
+    for (pinfo = PSD->suspended_list; pinfo; pinfo = pinfo->next)
     {
         if (pinfo->thread == thread)
             break;

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def?rev=660062&r1=660061&r2=660062&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def Sun May 25 17:33:06 2008
@@ -53,7 +53,6 @@
 hythread_get_id
 hythread_get_thread
 hythread_get_thread_times
-hythread_get_thread_stacksize
 hythread_struct_init
 hythread_cancel_all
 hythread_group_create

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp?rev=660062&r1=660061&r2=660062&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp Sun May 25 17:33:06 2008
@@ -39,7 +39,6 @@
 hythread_resume;
 hythread_monitor_notify;
 hythread_get_priority;
-hythread_get_thread_stacksize;
 hythread_tls_get;
 hythread_tls_get_request_offset;
 hythread_get_hythread_offset_in_tls;

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_attrs.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_attrs.c?rev=660062&r1=660061&r2=660062&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_attrs.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_attrs.c Sun May 25 17:33:06 2008
@@ -38,7 +38,7 @@
  * @returns 0 on success or negative value on failure (priority wasn't changed)
  */
 IDATA VMCALL hythread_set_priority(hythread_t thread, UDATA priority) {
-    int r = os_thread_set_priority(thread->os_handle, priority);
+    int r = port_thread_set_priority(thread->os_handle, priority);
     if (r) return r;
     thread->priority = priority;
     return 0;

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c?rev=660062&r1=660061&r2=660062&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c Sun May 25 17:33:06 2008
@@ -87,7 +87,6 @@
     self = hythread_self();
     new_thread->library = self ? self->library : TM_LIBRARY;
     new_thread->priority = priority ? priority : HYTHREAD_PRIORITY_NORMAL;
-    new_thread->stacksize = stacksize ? stacksize : TM_DEFAULT_STACKSIZE;
     
     if (!wrapper) {
         hythread_start_proc_data_t start_proc_data;
@@ -112,9 +111,10 @@
     }
 
     // Need to make sure thread will not register itself with a thread group
-    // until os_thread_create returned and initialized thread->os_handle properly.
+    // until port_thread_create returned and initialized thread->os_handle properly.
     hythread_global_lock();
-    result = os_thread_create(&new_thread->os_handle, new_thread->stacksize,
+    result = port_thread_create(&new_thread->os_handle,
+            stacksize ? stacksize : TM_DEFAULT_STACKSIZE,
             priority, wrapper, data);
     assert(/* error */ result || new_thread->os_handle /* or thread created ok */);
     hythread_global_unlock();
@@ -166,6 +166,7 @@
                          hythread_library_t lib,
                          hythread_group_t group)
 {
+    int res;
     IDATA status;
     hythread_t self = hythread_self();
 
@@ -176,13 +177,19 @@
 
     new_thread->library = TM_LIBRARY;
     if (self) {
-        // to avoid creating multiple OS handle
+        // to avoid creating multiple OS handles
         new_thread->os_handle = self->os_handle;
     } else {
-        new_thread->os_handle = os_thread_current();
+        new_thread->os_handle = port_thread_current();
     }
     assert(new_thread->os_handle);
 
+    res = port_thread_attach();
+    // It's OK to have an error here when Port shared library
+    // is not available yet; only signals/crash handling will
+    // not be available for the thread
+    //assert(res == 0);
+
     CTRACE(("TM: native attached: native: %p ", new_thread));
 
     status = hythread_set_to_group(new_thread,
@@ -277,6 +284,9 @@
     // Detach if thread is attached to group.
     hythread_remove_from_group(thread);
 
+    if (thread == hythread_self()) // Detach current thread only
+        port_thread_detach();
+
     // FIXME - uncomment after TM state transition complete
     // release thread data
     //hythread_struct_release(thread);
@@ -525,7 +535,7 @@
     osthread_t os_handle = thread->os_handle;
     hythread_detach(thread);
     port_thread_cancel(os_handle);
-    os_thread_join(os_handle);
+    port_thread_join(os_handle);
 }
 
 /** 
@@ -679,7 +689,7 @@
         hythread_monitor_t monitor;
 
         // release thread OS handle
-        result = os_thread_free(new_thread->os_handle);
+        result = port_thread_free_handle(new_thread->os_handle);
         assert(0 == result);
 
         resume = new_thread->resume_event;
@@ -697,7 +707,6 @@
 
     new_thread->java_status = jstatus;
     new_thread->priority   = HYTHREAD_PRIORITY_NORMAL;
-    new_thread->stacksize = os_get_foreign_thread_stack_size();
 
     port_mutex_lock(&new_thread->mutex);
     new_thread->state = TM_THREAD_STATE_NEW;
@@ -754,7 +763,7 @@
     start_proc = start_proc_data.proc;
 
     CTRACE(("TM: native thread started: native: %p tm: %p",
-        apr_os_thread_current(), thread));
+        port_thread_current(), thread));
 
     // check hythread library state
     if (hythread_lib_state() != TM_LIBRARY_STATUS_INITIALIZED) {
@@ -774,7 +783,7 @@
         hythread_set_self(NULL);
 
         CTRACE(("TM: native thread terminated due to shutdown: native: %p tm: %p",
-            apr_os_thread_current(), thread));
+            port_thread_current(), thread));
 
         // release hythread global lock
         status = hythread_global_unlock();
@@ -832,7 +841,7 @@
         hythread_monitor_exit(monitor);
     }
     hythread_detach_ex(NULL);
-    os_thread_exit(0);
+    port_thread_exit(0);
     // unreachable statement
     abort();
 }
@@ -847,14 +856,10 @@
  * @returns     0 on success, system error code otherwise
  */
 UDATA hythread_get_thread_times(hythread_t thread, int64* pkernel, int64* puser) {
-    return os_get_thread_times(thread->os_handle, pkernel, puser);
+    return port_get_thread_times(thread->os_handle, pkernel, puser);
 }
 
 
-UDATA hythread_get_thread_stacksize(hythread_t thread) {
-    return thread->stacksize;
-}
-
 IDATA VMCALL hythread_thread_lock(hythread_t thread) {
     assert(thread);
     return port_mutex_lock(&thread->mutex);

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=660062&r1=660061&r2=660062&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h Sun May 25 17:33:06 2008
@@ -304,17 +304,7 @@
 /*
  * portability functions, private for thread module
  */
-int os_thread_create(osthread_t* phandle, UDATA stacksize, UDATA priority,
-        hythread_wrapper_t func, void *data);
-int os_thread_set_priority(osthread_t thread, int priority);
-osthread_t os_thread_current();
-int os_thread_free(osthread_t os_thread);
-void os_thread_exit(IDATA status);
-int os_thread_join(osthread_t os_thread);
-int os_get_thread_times(osthread_t os_thread, int64* pkernel, int64* puser);
-
 int os_cond_timedwait(hycond_t *cond, osmutex_t *mutex, I_64 ms, IDATA nano);
-UDATA os_get_foreign_thread_stack_size();
 
 
 #ifdef __cplusplus

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/exceptions.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/exceptions.h?rev=660062&r1=660061&r2=660062&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/exceptions.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/exceptions.h Sun May 25 17:33:06 2008
@@ -269,10 +269,7 @@
 void exn_rethrow();
 void exn_rethrow_if_pending();
 
-bool set_guard_stack();
 typedef struct VM_thread * vm_thread_t;
-void remove_guard_stack(vm_thread_t vm_thread);
-void init_stack_info();
 void* get_exception_catch_stack_addr(void* curr_ip);
 VMEXPORT size_t get_available_stack_size();
 VMEXPORT bool check_available_stack_size(size_t required_size);

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp?rev=660062&r1=660061&r2=660062&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp Sun May 25 17:33:06 2008
@@ -35,6 +35,7 @@
 #include "object_handles.h"
 #include "vm_arrays.h"
 #include "vm_strings.h"
+#include "port_thread.h"
 #include "cci.h"
 #include "ExpandableMemBlock.h"
 
@@ -120,15 +121,17 @@
     clear_exception_internal();
     tmn_suspend_enable_recursive();
 
-    // if quard stack should be restored - restores it
+    // This will restore quard stack if needed
     if (p_TLS_vmthread->restore_guard_page) {
-        bool result = set_guard_stack();
+        int res = port_thread_restore_guard_page();
 
         // if guard stack can't be restored raise SOE
-        if (result == false) {
+        if (res != 0) {
             Global_Env *env = VM_Global_State::loader_env;
             exn_raise_by_class(env->java_lang_StackOverflowError_Class);
         }
+
+        p_TLS_vmthread->restore_guard_page = false;
     }
 }
 

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=660062&r1=660061&r2=660062&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 Sun May 25 17:33:06 2008
@@ -652,16 +652,16 @@
     // si_create_from_registers uses large stack space,
     // so guard page restored after its invoke.
     if (p_TLS_vmthread->restore_guard_page) {
-        bool result = set_guard_stack();
+        int res = port_thread_restore_guard_page();
 
-        if (result == false) {
+        if (res != 0) {
             Global_Env *env = VM_Global_State::loader_env;
 
             if (si_is_native(si)) {
                 m2n_set_last_frame(prev_m2n);
 
-                if ((interpreter_enabled() || (!prev_m2n) 
-                        || (m2n_get_frame_type(prev_m2n) & FRAME_NON_UNWINDABLE))) {
+                if ((interpreter_enabled() || (!prev_m2n) ||
+                        (m2n_get_frame_type(prev_m2n) & FRAME_NON_UNWINDABLE))) {
                     exn_raise_by_class(env->java_lang_StackOverflowError_Class);
                 } else {
                     //si_free(si);
@@ -672,6 +672,8 @@
                 exn_throw_by_class(env->java_lang_StackOverflowError_Class);
             }
         }
+
+        p_TLS_vmthread->restore_guard_page = false;
     }
 
     si_transfer_control(si);
@@ -699,16 +701,16 @@
     // but befor ti agent callback invokation, 
     // because it should work on protected page.
     if (p_TLS_vmthread->restore_guard_page) {
-        bool result = set_guard_stack();
+        int res = port_thread_restore_guard_page();
 
-        if (result == false) {
+        if (res != 0) {
             Global_Env *env = VM_Global_State::loader_env;
 
             if (si_is_native(si)) {
                 m2n_set_last_frame(prev_m2n);
 
-                if ((interpreter_enabled() || (!prev_m2n) 
-                        || (m2n_get_frame_type(prev_m2n) & FRAME_NON_UNWINDABLE))) {
+                if ((interpreter_enabled() || (!prev_m2n) ||
+                        (m2n_get_frame_type(prev_m2n) & FRAME_NON_UNWINDABLE))) {
                     exn_raise_by_class(env->java_lang_StackOverflowError_Class);
                 } else {
                     //si_free(si);
@@ -719,6 +721,8 @@
                 exn_throw_by_class(env->java_lang_StackOverflowError_Class);
             }
         }
+
+        p_TLS_vmthread->restore_guard_page = false;
     }
 
     if (!si_is_native(si))
@@ -732,6 +736,7 @@
         *exn_obj = jvmti_jit_exception_catch_event_callback_call( *exn_obj,
                 catch_method_jit, catch_method, catch_method_location);
     }
+
     si_transfer_control(si);
 }
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp?rev=660062&r1=660061&r2=660062&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp Sun May 25 17:33:06 2008
@@ -189,8 +189,6 @@
     jni_env->reserved0 = (void *) 0x1234abcd;
     *p_jni_env = jni_env;
 
-    init_stack_info();
-
     m2n_null_init(p_m2n);
     m2n_set_last_frame(p_m2n);
 
@@ -248,11 +246,6 @@
         gc_thread_kill(&p_vm_thread->_gc_private_information);
     }
 
-#ifdef PLATFORM_POSIX
-    // Remove guard page on the stack on linux
-    remove_guard_stack(p_vm_thread);
-#endif // PLATFORM_POSIX
-
     if (ti_is_enabled())
     {
         apr_status_t UNREF status;

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_java_basic.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_java_basic.cpp?rev=660062&r1=660061&r2=660062&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_java_basic.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_java_basic.cpp Sun May 25 17:33:06 2008
@@ -26,6 +26,7 @@
 #include "open/vm_properties.h"
 #include "jthread.h"
 #include "vm_threads.h"
+#include "port_thread.h"
 #include "jni.h"
 
 static jmethodID jthread_get_run_method(JNIEnv * env, jthread java_thread);
@@ -86,7 +87,7 @@
         hythread_set_self(NULL);
 
         CTRACE(("TM: native thread terminated due to shutdown: native: %p tm: %p",
-            apr_os_thread_current(), native_thread));
+            port_thread_current(), native_thread));
 
         // FIXME - uncomment after TM state transition complete
         //STD_FREE(native_thread);
@@ -127,7 +128,7 @@
     vm_thread->daemon = start_proc_data.daemon;
 
     CTRACE(("TM: Java thread started: id=%d OS_handle=%p",
-           hythread_get_id(native_thread), apr_os_thread_current()));
+           hythread_get_id(native_thread), port_thread_current()));
 
     if (!vm_thread->daemon) {
         status = hythread_increase_nondaemon_threads_count(native_thread);
@@ -179,7 +180,7 @@
     assert(status == TM_ERROR_NONE);
 
     CTRACE(("TM: Java thread finished: id=%d OS_handle=%p",
-        hythread_get_id(native_thread), apr_os_thread_current()));
+        hythread_get_id(native_thread), port_thread_current()));
 
     hythread_detach_ex(native_thread);
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/signals.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/signals.cpp?rev=660062&r1=660061&r2=660062&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/signals.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/signals.cpp Sun May 25 17:33:06 2008
@@ -23,9 +23,164 @@
 #include "init.h"
 #include "vm_threads.h"
 #include "environment.h"
+#include "exceptions.h"
 #include "signals.h"
 
 
+#ifdef PLATFORM_POSIX
+
+#if defined(_EM64T_)
+#define RESTORE_STACK_SIZE 0x0400
+#elif defined (_IA32_)
+#define RESTORE_STACK_SIZE 0x0100
+#else // IPF
+#define RESTORE_STACK_SIZE 0x0200
+#endif
+
+#else // WINDOWS
+#define RESTORE_STACK_SIZE 0x0100
+#endif
+
+
+size_t get_available_stack_size()
+{
+    size_t stack_addr = (size_t)port_thread_get_stack_address();
+    size_t stack_size = port_thread_get_effective_stack_size();
+    size_t used_stack_size = stack_addr - (size_t)&stack_size;
+    size_t available_stack_size = stack_size - used_stack_size;
+
+    return (available_stack_size > 0) ? available_stack_size : 0;
+}
+
+bool check_available_stack_size(size_t required_size)
+{
+    size_t available_stack_size = get_available_stack_size();
+
+    if (available_stack_size < required_size)
+    {
+        port_thread_clear_guard_page();
+        p_TLS_vmthread->restore_guard_page = true;
+        Global_Env *env = VM_Global_State::loader_env;
+        exn_raise_by_class(env->java_lang_StackOverflowError_Class);
+        return false;
+    }
+
+    return true;
+}
+
+static inline size_t get_available_stack_size(void* sp) {
+    size_t stack_addr = (size_t)port_thread_get_stack_address();
+    size_t stack_size = port_thread_get_effective_stack_size();
+    size_t used_stack_size = stack_addr - (size_t)sp;
+    size_t available_stack_size = stack_size - used_stack_size;
+
+    return (available_stack_size > 0) ? available_stack_size : 0;
+}
+
+bool check_stack_size_enough_for_exception_catch(void* sp)
+{
+    size_t stack_addr = (size_t)port_thread_get_stack_address();
+    size_t stack_size = port_thread_get_effective_stack_size();
+    size_t used_stack_size = stack_addr - (size_t)sp;
+    size_t available_stack_size = stack_size - used_stack_size;
+
+    return RESTORE_STACK_SIZE < available_stack_size;
+}
+
+Boolean stack_overflow_handler(port_sigtype UNREF signum, Registers* regs, void* fault_addr)
+{
+    TRACE2("signals", ("SOE detected at ip=%p, sp=%p",
+                            regs->get_ip(), regs->get_sp()));
+
+    vm_thread_t vmthread = get_thread_ptr();
+    Global_Env* env = VM_Global_State::loader_env;
+    void* saved_ip = regs->get_ip();
+    void* new_ip = NULL;
+
+    if (is_in_ti_handler(vmthread, saved_ip))
+    {
+        new_ip = vm_get_ip_from_regs(vmthread);
+        regs->set_ip(new_ip);
+    }
+
+    if (!vmthread || env == NULL)
+        return FALSE; // Crash
+
+    port_thread_postpone_guard_page();
+    vmthread->restore_guard_page = true;
+
+    // Pass exception to NCAI exception handler
+    bool is_handled = 0;
+    ncai_process_signal_event((NativeCodePtr)regs->get_ip(),
+                                (jint)signum, false, &is_handled);
+    if (is_handled)
+    {
+        if (new_ip)
+            regs->set_ip(saved_ip);
+        return TRUE;
+    }
+
+    Class* exn_class = env->java_lang_StackOverflowError_Class;
+
+    if (is_in_java(regs))
+    {
+        signal_throw_java_exception(regs, exn_class);
+    }
+    else if (is_unwindable())
+    {
+        if (hythread_is_suspend_enabled())
+            hythread_suspend_disable();
+        signal_throw_exception(regs, exn_class);
+    } else {
+        exn_raise_by_class(exn_class);
+    }
+
+    if (new_ip && regs->get_ip() == new_ip)
+        regs->set_ip(saved_ip);
+
+    return TRUE;
+}
+
+Boolean null_reference_handler(port_sigtype UNREF signum, Registers* regs, void* fault_addr)
+{
+    TRACE2("signals", "NPE detected at " << regs->get_ip());
+
+    vm_thread_t vmthread = get_thread_ptr();
+    Global_Env* env = VM_Global_State::loader_env;
+    void* saved_ip = regs->get_ip();
+    void* new_ip = NULL;
+
+    if (is_in_ti_handler(vmthread, saved_ip))
+    {
+        new_ip = vm_get_ip_from_regs(vmthread);
+        regs->set_ip(new_ip);
+    }
+
+    if (!vmthread || env == NULL)
+        return FALSE; // Crash
+
+    if (!is_in_java(regs) || interpreter_enabled())
+        return FALSE; // Crash
+
+    // Pass exception to NCAI exception handler
+    bool is_handled = 0;
+    ncai_process_signal_event((NativeCodePtr)regs->get_ip(),
+                                (jint)signum, false, &is_handled);
+    if (is_handled)
+    {
+        if (new_ip)
+            regs->set_ip(saved_ip);
+        return TRUE;
+    }
+
+    signal_throw_java_exception(regs, env->java_lang_NullPointerException_Class);
+
+    if (new_ip && regs->get_ip() == new_ip)
+        regs->set_ip(saved_ip);
+
+    return TRUE;
+}
+
 Boolean abort_handler(port_sigtype UNREF signum, Registers* UNREF regs, void* fault_addr)
 {
     TRACE2("signals", "Abort detected at " << regs->get_ip());