harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gshiman...@apache.org
Subject svn commit: r633414 [1/2] - in /harmony/enhanced/drlvm/trunk: make/vm/ vm/include/open/ vm/port/include/ vm/port/src/thread/linux/ vm/port/src/thread/win/ vm/thread/src/ vm/thread/src/linux/ vm/thread/src/win/ vm/vmcore/include/ vm/vmcore/src/jvmti/ vm...
Date Tue, 04 Mar 2008 10:27:05 GMT
Author: gshimansky
Date: Tue Mar  4 02:26:56 2008
New Revision: 633414

URL: http://svn.apache.org/viewvc?rev=633414&view=rev
Log:
Applied patches 0011 and 0012 from HARMONY-5504
[drlvm][port] Restructure DRLVM's sources to extract most of platform dependent code into portlib

Patches move signals and exceptions handlers to port library and implement
universal transfer control code to be used in crash handler. Singlas and
exceptions handling code in VM was adopted to use this functionality.


Added:
    harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_em64t.c
      - copied, changed from r633236, harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp
    harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_ia32.c
      - copied, changed from r633236, harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp
    harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_ipf.c
      - copied, changed from r633236, harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_ipf.cpp
    harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_os.c   (with props)
    harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_em64t.c
      - copied, changed from r633236, harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/em64t/nt_exception_filter.cpp
    harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_ia32.c   (with props)
    harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_os.c   (with props)
Removed:
    harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_ipf.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/em64t/nt_exception_filter.cpp
Modified:
    harmony/enhanced/drlvm/trunk/make/vm/port.xml
    harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h
    harmony/enhanced/drlvm/trunk/vm/include/open/ncai_thread.h
    harmony/enhanced/drlvm/trunk/vm/port/include/port_thread.h
    harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_asm_em64t.s
    harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_asm_ia32.s
    harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_asm_em64t.asm
    harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_asm_ia32.asm
    harmony/enhanced/drlvm/trunk/vm/thread/src/linux/os_thread.c
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_thin_monitor.c
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ncai_common.c
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h
    harmony/enhanced/drlvm/trunk/vm/thread/src/win/os_thread.c
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/exceptions_jit.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_break_intf.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_threads.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_em64t.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_ia32.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_ipf.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_linux.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/utils/ncai_utils_win.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_manager.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/crash_handler.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/ia32_em64t/signals_common.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/include/platform_lowlevel.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/include/signals_common.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/os_wrapper.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ipf.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/stack_dump_platf.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/native_stack.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/em64t/exception_handlers.asm
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/include/exception_filter.h

Modified: harmony/enhanced/drlvm/trunk/make/vm/port.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/make/vm/port.xml?rev=633414&r1=633413&r2=633414&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/make/vm/port.xml (original)
+++ harmony/enhanced/drlvm/trunk/make/vm/port.xml Tue Mar  4 02:26:56 2008
@@ -38,7 +38,6 @@
             <include name="file_io/linux/*.c" if="is.unix"/>
             <include name="misc/linux/*.c" if="is.unix"/>
             <include name="vmem/linux/*.c" if="is.unix"/>
-            <include name="thread/linux/*.c" if="is.unix"/>
 
             <include name="atomic/linux/*.c" if="is.unix" unless="is.ia64"/>
             <include name="atomic/linux_ipf/*.c" if="is.unix.ia64"/>
@@ -48,13 +47,19 @@
             <include name="file_io/win/*.c" if="is.windows"/>
             <include name="misc/win/*.c" if="is.windows"/>
             <include name="vmem/win/*.c" if="is.windows"/>
-            <include name="thread/win/*.c" if="is.windows"/>
             <include name="file_io/*.c"/>
 
             <include name="modules/*.c"/>
             <include name="modules/linux/*.c" if="is.unix"/>
             <include name="modules/win/*.c" if="is.windows"/>
-            <include name="thread/linux/*ipf.cpp" if="is.unix.ia64"/>
+
+            <include name="thread/linux/*_os.c" if="is.unix"/>
+            <include name="thread/linux/*ia32.c" if="is.unix.x86"/>
+            <include name="thread/linux/*em64t.c" if="is.unix.x86_64"/>
+            <include name="thread/linux/*ipf.c" if="is.unix.ia64"/>
+            <include name="thread/win/*_os.c" if="is.windows"/>
+            <include name="thread/win/*ia32.c" if="is.windows.x86"/>
+            <include name="thread/win/*em64t.c" if="is.windows.x86_64"/>
         </patternset>
 
         <depend-includes paths="port.includes"/>

Modified: harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h?rev=633414&r1=633413&r2=633414&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h Tue Mar  4 02:26:56 2008
@@ -153,10 +153,17 @@
 #include "hycond_win.h"
 #endif // _WIN32
 
-#if defined(__linux__) || defined(FREEBSD) 
+#if defined(__linux__) || defined(FREEBSD)
+
+#include <sys/ucontext.h>
 #define osthread_t pthread_t
+#define thread_context_t ucontext_t
+
 #elif _WIN32
+
 #define osthread_t HANDLE
+#define thread_context_t CONTEXT
+
 #else // !_WIN32 && !__linux__
 #error "threading is only supported on __linux__ or _WIN32"
 #endif // !_WIN32 && !__linux__

Modified: harmony/enhanced/drlvm/trunk/vm/include/open/ncai_thread.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/ncai_thread.h?rev=633414&r1=633413&r2=633414&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/ncai_thread.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/ncai_thread.h Tue Mar  4 02:26:56 2008
@@ -33,16 +33,7 @@
 
 #include "jvmti_types.h"
 #include "hythread_ext.h"
-
-
-#ifdef WIN32
-/* Thread context definition for Windows */
-typedef CONTEXT  os_thread_context_t;
-#else
-/* Thread context definition for UNIX-like systems */
-#include <sys/ucontext.h>
-typedef ucontext_t  os_thread_context_t;
-#endif
+#include "port_thread.h"
 
 
 #ifdef __cplusplus
@@ -62,9 +53,9 @@
 hythread_get_suspend_count_native PROTOTYPE((hythread_t thread));
 
 extern HY_CFUNC IDATA VMCALL
-hythread_get_thread_context PROTOTYPE((hythread_t thread, os_thread_context_t* pcontext));
+hythread_get_thread_context PROTOTYPE((hythread_t thread, thread_context_t* pcontext));
 extern HY_CFUNC IDATA VMCALL
-hythread_set_thread_context PROTOTYPE((hythread_t thread, os_thread_context_t* pcontext));
+hythread_set_thread_context PROTOTYPE((hythread_t thread, thread_context_t* pcontext));
 
 //@}
 

Modified: harmony/enhanced/drlvm/trunk/vm/port/include/port_thread.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/include/port_thread.h?rev=633414&r1=633413&r2=633414&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/include/port_thread.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/include/port_thread.h Tue Mar  4 02:26:56 2008
@@ -23,8 +23,32 @@
  * @brief PORT thread support
  */
 
+/* For osthread_t and thread_context_t types */
+#include "open/hythread_ext.h"
 
 
+/* Thread context definition for UNIX-like systems */
+#if defined(LINUX) || defined(FREEBSD) 
+#if defined(LINUX)
+
+#include <sys/types.h>
+#include <linux/unistd.h>
+#include <errno.h>
+
+#ifdef _syscall0
+static _syscall0(pid_t, gettid)/* static definition */
+#else /* _syscall0 */
+#include <sys/syscall.h>
+#include <unistd.h>
+#define gettid() ((pid_t)syscall(__NR_gettid))
+#endif /* _syscall0 */
+
+#else /* !LINUX */
+#define gettid() getpid()
+#endif
+
+#endif /* LINUX || FREEBSD */
+
 /* To skip platform_types.h inclusion */
 typedef struct Registers Registers;
 
@@ -33,13 +57,70 @@
 #endif /* __cplusplus */
 
 
-/** @name Threads manipulation and information
+/** @name OS thread operations
  */
 //@{
 
 
+void port_thread_yield_other(osthread_t thread);
+int port_thread_cancel(osthread_t os_thread);
+
+int port_thread_suspend(osthread_t thread);
+int port_thread_resume(osthread_t thread);
+int port_thread_get_suspend_count(osthread_t thread);
+
+int port_thread_get_context(osthread_t thread, thread_context_t* pcontext);
+int port_thread_set_context(osthread_t thread, thread_context_t* pcontext);
+
+void port_thread_context_to_regs(Registers* regs, thread_context_t* context);
+void port_thread_regs_to_context(thread_context_t* context, Registers* regs);
+
 /* Transfer control to specified register context */
-void transfer_to_regs(Registers* regs);
+void port_transfer_to_regs(Registers* regs);
+
+/**
+* Prepares 'Registers' structure and stack area pointed in for calling
+* 'fn' function with a set of arguments provided in variable args list.
+* THe 'fn' function is called through a special stub function with
+* preserving 'red zone' on Linux and clearing direction flag on Windows.
+* After returning from 'fn' and stub, processor registers are restored
+* with a values provided in 'regs' argument.
+* The function can be used to prepare register context for transfering
+* a control to a signal/exception handling function out of the OS handler.
+*
+* When the first argument passed to 'fn' is the same 'regs' pointer, its
+* value is substituted with the pointer stored 'Registers' structure used
+* to restore register context. If 'fn' function modifies the context
+* pointed by the first argument, these changes will take effect after
+* returning from 'fn'.
+*
+* The stub for calling 'fn' is written in assembler language; 'Registers'
+* fields and size are hardcoded. It would be better to rewrite it using
+* encoder in future, to keep control on 'Registers' structure and size.
+*
+* @param [in] fn    - the address of the function to be called
+* @param [in] regs  - the register context
+* @param [in] num   - the number of parameters passed to the 'fn' function
+*                     in the variable args list (6 args at maximum)
+* @param [in] ...   - the parameters for 'fn'; should all be void* or of
+*                     the same size (pointer-sized)
+*/
+void port_set_longjump_regs(void* fn, Registers* regs, int num, ...);
+
+/**
+* The same as 'port_set_longjump_regs', but transfers a control to the
+* prepared registers context by itself.
+* Actually it's a combination of 'port_set_longjump_regs' and
+* 'port_transfer_to_regs' functions, but 'regs' fields are kept unchanged.
+*
+* @param [in] fn    - the address of the function to be called
+* @param [in] regs  - the register context
+* @param [in] num   - the number of parameters passed to the 'fn' function
+*                     in the variable args list (6 args at maximum)
+* @param [in] ...   - the parameters for 'fn'; should all be void* or of
+*                     the same size (pointer-sized)
+*/
+void port_transfer_to_function(void* fn, Registers* regs, int num, ...);
 
 
 

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_asm_em64t.s
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_asm_em64t.s?rev=633414&r1=633413&r2=633414&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_asm_em64t.s (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_asm_em64t.s Tue Mar  4 02:26:56 2008
@@ -41,11 +41,11 @@
 // uint32 eflags;; 88h
 // };
 //
-// void transfer_to_regs(Registers* regs)
+// void port_transfer_to_regs(Registers* regs)
 
-.globl transfer_to_regs
-	.type	transfer_to_regs, @function
-transfer_to_regs:
+.globl port_transfer_to_regs
+	.type	port_transfer_to_regs, @function
+port_transfer_to_regs:
     movq    %rdi, %rdx // regs pointer (1st param - RDI) -> RDX
 
     movq    0x08(%rdx), %rbp // RBP field
@@ -80,3 +80,38 @@
     movq    (%rsp), %rsp     // load new RSP
     jmpq    * -0x88(%rsp)    // JMP to new RIP
 
+
+// void port_longjump_stub(void)
+//
+// after returning from the called function, RSP points to the 2 argument
+// slots in the stack. Saved Registers structure pointer is (RSP + 48)
+//
+// | interrupted |
+// |  program    | <- RSP where the program was interrupted by signal
+// |-------------|
+// | 0x80 bytes  | <- 'red zone' - we will not change it
+// |-------------|
+// | return addr |
+// | from stub   | <- for using in port_transfer_to_regs as [(new RSP) - 128 - 8]
+// |-------------|
+// |    saved    |
+// |  Registers  | <- to restore register context
+// |-------------|
+// | [alignment] | <- align Regs pointer to 16-bytes boundary
+// |-------------|
+// |  pointer to |
+// |  saved Regs | <- (RSP + 128)
+//                // |-------------|
+//                // | 0x80 bytes  | <- 'red zone'
+// |-------------|
+// | return addr |
+// |  from 'fn'  | <- address to return to the port_longjump_stub
+// |-------------|
+
+.globl port_longjump_stub
+	.type	port_longjump_stub, @function
+port_longjump_stub:
+//    movq    128(%rsp), %rcx // load RCX with the address of saved Registers
+    movq    (%rsp), %rcx // load RCX with the address of saved Registers
+    callq   port_transfer_to_regs   // restore context
+    ret                             // dummy RET - unreachable

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_asm_ia32.s
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_asm_ia32.s?rev=633414&r1=633413&r2=633414&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_asm_ia32.s (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_asm_ia32.s Tue Mar  4 02:26:56 2008
@@ -30,11 +30,11 @@
 // uint32 eflags; +24
 // };
 //
-// void transfer_to_regs(Registers* regs)
+// void port_transfer_to_regs(Registers* regs)
 
-.globl transfer_to_regs
-	.type	transfer_to_regs, @function
-transfer_to_regs:
+.globl port_transfer_to_regs
+	.type	port_transfer_to_regs, @function
+port_transfer_to_regs:
     movl    0x04(%esp), %edx // store regs pointer to EDX
     movl    0x20(%edx), %ebx // EIP field -> EBX
     movl    0x1C(%edx), %ecx // ESP field
@@ -56,3 +56,38 @@
     movl    0x0C(%edx), %edx // EDX field
     movl    0x04(%esp), %esp // ((new ESP - 4) -> ESP
     ret                      // JMP by RET
+
+
+// void port_longjump_stub(void)
+//
+// after returning from the called function, EBP points to the pointer
+// to saved Registers structure
+//
+// | interrupted |
+// |  program    | <- ESP where the program was interrupted by signal
+// |-------------|
+// | return addr |
+// | from stub   | <- for using in port_transfer_to_regs
+// |-------------|
+// |    saved    |
+// |  Registers  | <- to restore register context
+// |-------------|
+// |  pointer to |
+// |  saved Regs | <- EBP
+// |-------------|
+// |  arg 5      | <-
+// |-------------|   |
+// ...............    - arguments for 'fn'
+// |-------------|   |
+// |  arg 0      | <-
+// |-------------|
+// | return addr |
+// |  from 'fn'  | <- address to return to the port_longjump_stub
+// |-------------|
+
+.globl port_longjump_stub
+	.type	port_longjump_stub, @function
+port_longjump_stub:
+    movl    %ebp, %esp    // ESP now points to the address of saved Registers
+    call    port_transfer_to_regs   // restore context
+    ret                             // dummy RET - unreachable

Copied: harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_em64t.c (from r633236, harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp)
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_em64t.c?p2=harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_em64t.c&p1=harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp&r1=633236&r2=633414&rev=633414&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_em64t.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_em64t.c Tue Mar  4 02:26:56 2008
@@ -16,13 +16,12 @@
  */
 
 
+#define  _GNU_SOURCE
 #include <sys/ucontext.h>
-#include <stdio.h>
-#include "vm_core_types.h"
-#include "signals_common.h"
+#include "port_thread.h"
 
 
-void ucontext_to_regs(Registers* regs, ucontext_t *uc)
+void port_thread_context_to_regs(Registers* regs, ucontext_t *uc)
 {
     regs->rax = uc->uc_mcontext.gregs[REG_RAX];
     regs->rcx = uc->uc_mcontext.gregs[REG_RCX];
@@ -44,7 +43,7 @@
     regs->eflags = uc->uc_mcontext.gregs[REG_EFL];
 }
 
-void regs_to_ucontext(ucontext_t *uc, Registers* regs)
+void port_thread_regs_to_context(ucontext_t *uc, Registers* regs)
 {
     uc->uc_mcontext.gregs[REG_RAX] = regs->rax;
     uc->uc_mcontext.gregs[REG_RCX] = regs->rcx;
@@ -66,28 +65,123 @@
     uc->uc_mcontext.gregs[REG_EFL] = regs->eflags;
 }
 
-// Max. 6 arguments can be set up
-void regs_push_param(Registers* pregs, POINTER_SIZE_INT param, int num)
+
+void port_longjump_stub(void);
+#define DIR_FLAG ((uint32)0x00000400)
+
+void port_set_longjump_regs(void* fn, Registers* regs, int num, ...)
 {
-    switch (num)
-    {
-    case 0:
-        pregs->rdi = param;
-        return;
-    case 1:
-        pregs->rsi = param;
-        return;
-    case 2:
-        pregs->rdx = param;
-        return;
-    case 3:
-        pregs->rcx = param;
-        return;
-    case 4:
-        pregs->r8 = param;
+    void** sp;
+    va_list ap;
+    int i;
+    size_t align;
+    void** p_pregs;
+    size_t rcount =
+        (sizeof(Registers) + sizeof(void*) - 1) / sizeof(void*);
+
+    if (!regs)
         return;
-    case 5:
-        pregs->r9 = param;
+
+    sp = (void**)regs->rsp - 16 - 1; /* preserve 128-bytes 'red zone' */
+    *sp = (void*)regs->rip;
+    align = !((rcount & 1) ^ (((uint64)sp & sizeof(void*)) != 0));
+    p_pregs = sp - rcount - align - 1;
+    sp = sp - rcount;
+    *((Registers*)sp) = *regs;
+    *p_pregs = (void*)sp;
+
+//    sp = p_pregs - 16 - 1; /* preserve 128-bytes 'red zone' */
+    sp = p_pregs - 1; /* set sp to return address */
+
+    va_start(ap, num);
+
+    if (num > 0)
+    {
+        void* arg = va_arg(ap, void*);
+        if (arg == regs)
+            regs->rdi = (uint64)(*p_pregs); /* Replace 1st arg */
+        else
+            regs->rdi = (uint64)arg;
+    }
+
+    if (num > 1)
+        regs->rsi = (uint64)va_arg(ap, void*);
+
+    if (num > 2)
+        regs->rdx = (uint64)va_arg(ap, void*);
+
+    if (num > 3)
+        regs->rcx = (uint64)va_arg(ap, void*);
+
+    if (num > 4)
+        regs->r8 = (uint64)va_arg(ap, void*);
+
+    if (num > 5)
+        regs->r9 = (uint64)va_arg(ap, void*);
+
+    *sp = (void*)&port_longjump_stub;
+    regs->rsp = (uint64)sp;
+    regs->rip = (uint64)fn;
+    regs->eflags = regs->eflags & ~DIR_FLAG;
+}
+
+void port_transfer_to_function(void* fn, Registers* pregs, int num, ...)
+{
+    void** sp;
+    va_list ap;
+    int i;
+    size_t align;
+    void** p_pregs;
+    size_t rcount =
+        (sizeof(Registers) + sizeof(void*) - 1) / sizeof(void*);
+    Registers regs;
+
+    if (!pregs)
         return;
+
+    regs = *pregs;
+
+    sp = (void**)regs.rsp - 16 - 1; /* preserve 128-bytes 'red zone' */
+    *sp = (void*)regs.rip;
+    align = !((rcount & 1) ^ (((uint64)sp & sizeof(void*)) != 0));
+    p_pregs = sp - rcount - align - 1;
+    sp = sp - rcount;
+    *((Registers*)sp) = regs;
+    *p_pregs = (void*)sp;
+
+//    sp = p_pregs - 16 - 1; /* preserve 128-bytes 'red zone' */
+    sp = p_pregs - 1; /* set sp to return address */
+
+    va_start(ap, num);
+
+    if (num > 0)
+    {
+        void* arg = va_arg(ap, void*);
+        if (arg == pregs)
+            regs.rdi = (uint64)(*p_pregs); /* Replace 1st arg */
+        else
+            regs.rdi = (uint64)arg;
     }
+
+    if (num > 1)
+        regs.rsi = (uint64)va_arg(ap, void*);
+
+    if (num > 2)
+        regs.rdx = (uint64)va_arg(ap, void*);
+
+    if (num > 3)
+        regs.rcx = (uint64)va_arg(ap, void*);
+
+    if (num > 4)
+        regs.r8 = (uint64)va_arg(ap, void*);
+
+    if (num > 5)
+        regs.r9 = (uint64)va_arg(ap, void*);
+
+    *sp = (void*)&port_longjump_stub;
+    regs.rsp = (uint64)sp;
+    regs.rip = (uint64)fn;
+    regs.eflags = regs.eflags & ~DIR_FLAG;
+
+    port_transfer_to_regs(&regs);
 }

Copied: harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_ia32.c (from r633236, harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp)
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_ia32.c?p2=harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_ia32.c&p1=harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp&r1=633236&r2=633414&rev=633414&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/linux/signals_ia32.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_ia32.c Tue Mar  4 02:26:56 2008
@@ -16,14 +16,14 @@
  */
 
 
+#define  _GNU_SOURCE
 #include <sys/ucontext.h>
-#include <stdio.h>
-#include "vm_core_types.h"
-#include "signals_common.h"
+#include <stdarg.h>
+#include "port_thread.h"
 
 
 #if defined(LINUX)
-void ucontext_to_regs(Registers* regs, ucontext_t *uc)
+void port_thread_context_to_regs(Registers* regs, ucontext_t *uc)
 {
     regs->eax = uc->uc_mcontext.gregs[REG_EAX];
     regs->ecx = uc->uc_mcontext.gregs[REG_ECX];
@@ -37,7 +37,7 @@
     regs->eflags = uc->uc_mcontext.gregs[REG_EFL];
 }
 
-void regs_to_ucontext(ucontext_t *uc, Registers* regs)
+void port_thread_regs_to_context(ucontext_t *uc, Registers* regs)
 {
     uc->uc_mcontext.gregs[REG_EAX] = regs->eax;
     uc->uc_mcontext.gregs[REG_ECX] = regs->ecx;
@@ -52,7 +52,7 @@
 }
 
 #elif defined(FREEBSD)
-void ucontext_to_regs(Registers* regs, ucontext_t *uc)
+void port_thread_context_to_regs(Registers* regs, ucontext_t *uc)
 {
     regs->eax = uc->uc_mcontext.mc_eax;
     regs->ecx = uc->uc_mcontext.mc_ecx;
@@ -66,7 +66,7 @@
     regs->eflags = uc->uc_mcontext.mc_eflags;
 }
 
-void regs_to_ucontext(ucontext_t *uc, Registers* regs)
+void port_thread_regs_to_context(ucontext_t *uc, Registers* regs)
 {
     uc->uc_mcontext.mc_eax = regs->eax;
     uc->uc_mcontext.mc_ecx = regs->ecx;
@@ -83,3 +83,88 @@
 #else
 #error need to add correct mcontext_t lookup for registers
 #endif
+
+
+void port_longjump_stub(void);
+#define DIR_FLAG ((uint32)0x00000400)
+
+void port_set_longjump_regs(void* fn, Registers* regs, int num, ...)
+{
+    void** sp;
+    va_list ap;
+    int i;
+    size_t rcount =
+        (sizeof(Registers) + sizeof(void*) - 1) / sizeof(void*);
+
+    if (!regs)
+        return;
+
+    sp = (void**)regs->esp - 1;
+    *sp = (void*)regs->eip;
+    sp = sp - rcount - 1;
+    *((Registers*)(sp + 1)) = *regs;
+    *sp = (void*)(sp + 1);
+    regs->ebp = (uint32)sp;
+
+    sp = sp - num - 1;
+
+    va_start(ap, num);
+
+    for (i = 1; i <= num; i = i + 1)
+    {
+        void* arg = va_arg(ap, void*);
+
+        if (i == 1 && arg == regs)
+            sp[i] = *((void**)regs->ebp); /* Replace 1st arg */
+        else
+            sp[i] = arg;
+    }
+
+    *sp = (void*)&port_longjump_stub;
+    regs->esp = (uint32)sp;
+    regs->eip = (uint32)fn;
+    regs->eflags = regs->eflags & ~DIR_FLAG;
+}
+
+void port_transfer_to_function(void* fn, Registers* pregs, int num, ...)
+{
+    void** sp;
+    va_list ap;
+    int i;
+    size_t rcount =
+        (sizeof(Registers) + sizeof(void*) - 1) / sizeof(void*);
+    Registers regs;
+
+    if (!pregs)
+        return;
+
+    regs = *pregs;
+
+    sp = (void**)regs.esp - 1;
+    *sp = (void*)regs.eip;
+    sp = sp - rcount - 1;
+    *((Registers*)(sp + 1)) = regs;
+    *sp = (void*)(sp + 1);
+    regs.ebp = (uint32)sp;
+
+    sp = sp - num - 1;
+
+    va_start(ap, num);
+
+    for (i = 1; i <= num; i = i + 1)
+    {
+        void* arg = va_arg(ap, void*);
+
+        if (i == 1 && arg == pregs)
+            sp[i] = *((void**)regs.ebp); /* Replace 1st arg */
+        else
+            sp[i] = arg;
+    }
+
+    *sp = (void*)&port_longjump_stub;
+    regs.esp = (uint32)sp;
+    regs.eip = (uint32)fn;
+    regs.eflags = regs.eflags & ~DIR_FLAG;
+
+    port_transfer_to_regs(&regs);
+}

Copied: harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_ipf.c (from r633236, harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_ipf.cpp)
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_ipf.c?p2=harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_ipf.c&p1=harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_ipf.cpp&r1=633236&r2=633414&rev=633414&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_ipf.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_ipf.c Tue Mar  4 02:26:56 2008
@@ -18,13 +18,56 @@
 #include <assert.h>
 #include <stdlib.h>
 #include <stdio.h>
-#include "open/platform_types.h"
+#include <sys/ucontext.h>
+#include "port_thread.h"
 
 
-void transfer_to_regs(Registers* regs)
+void port_transfer_to_regs(Registers* regs)
 {
     // FIXME: not implemented
-    fprintf(stderr, "FIXME: transfer_to_regs: not implemented\n");
+    fprintf(stderr, "FIXME: port_transfer_to_regs: not implemented\n");
+    assert(0);
+    abort();
+}
+
+void port_thread_context_to_regs(Registers* regs, ucontext_t* uc)
+{
+    memcpy(regs->gr, uc->uc_mcontext.sc_gr, sizeof(regs->gr));
+    memcpy(regs->fp, uc->uc_mcontext.sc_fr, sizeof(regs->fp));
+    memcpy(regs->br, uc->uc_mcontext.sc_br, sizeof(regs->br));
+
+    regs->preds = uc->uc_mcontext.sc_pr;
+    regs->nats  = uc->uc_mcontext.sc_ar_rnat;
+    regs->pfs   = uc->uc_mcontext.sc_ar_pfs;
+    regs->bsp   = (uint64*)uc->uc_mcontext.sc_ar_bsp;
+    regs->ip    = uc->uc_mcontext.sc_ip;
+}
+
+void port_thread_regs_to_context(ucontext_t* uc, Registers* regs)
+{
+    memcpy(uc->uc_mcontext.sc_gr, regs->gr, sizeof(regs->gr));
+    memcpy(uc->uc_mcontext.sc_fr, regs->fp, sizeof(regs->fp));
+    memcpy(uc->uc_mcontext.sc_br, regs->br, sizeof(regs->br));
+
+    uc->uc_mcontext.sc_pr      = regs->preds;
+    uc->uc_mcontext.sc_ar_rnat = regs->nats;
+    uc->uc_mcontext.sc_ar_pfs  = regs->pfs;
+    uc->uc_mcontext.sc_ar_bsp  = (uint64)regs->bsp;
+    uc->uc_mcontext.sc_ip      = regs->ip;
+}
+
+void port_set_longjump_regs(void* fn, Registers* regs, int num, ...)
+{
+    // FIXME: not implemented
+    fprintf(stderr, "FIXME: port_set_longjump_regs: not implemented\n");
+    assert(0);
+    abort();
+}
+
+void port_transfer_to_function(void* fn, Registers* pregs, int num, ...)
+{
+    // FIXME: not implemented
+    fprintf(stderr, "FIXME: port_transfer_to_function: not implemented\n");
     assert(0);
     abort();
 }

Added: 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=633414&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_os.c (added)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/thread/linux/thread_os.c Tue Mar  4 02:26:56 2008
@@ -0,0 +1,522 @@
+/*
+ *  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.
+ */
+
+#define  _GNU_SOURCE
+#include <assert.h>
+#include <sched.h>		// sched_param
+#include <semaphore.h>
+#include <unistd.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <stdlib.h>
+#include "port_thread.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;
+
+
+/* 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);
+
+
+/**
+ * Calculates absolute time in future for sem_timedwait timeout.
+ * @param ptime The pointer to time structure to fill
+ * @param delay Desired timeout in ns; not greater than 10^9 (1s)
+ */
+static inline __attribute__((always_inline))
+void get_exceed_time(struct timespec* ptime, long delay)
+{
+    clock_gettime(CLOCK_REALTIME, ptime);
+
+    ptime->tv_nsec += delay;
+    if (ptime->tv_nsec >= 1000000000L) // overflow
+    {
+        ptime->tv_nsec -= 1000000000L;
+        ++ptime->tv_sec;
+    }
+}
+
+/**
+ * Terminates the os thread.
+ */
+int port_thread_cancel(osthread_t os_thread)
+{
+    int status;
+    os_thread_info_t* pinfo;
+
+    if (!suspend_init_lock())
+        return -1;
+
+    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 port_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 port_thread_suspend(osthread_t thread)
+{
+    int status;
+    os_thread_info_t* pinfo;
+
+    if (!thread)
+        return -1;
+
+    if (!suspend_init_lock())
+        return -1;
+
+    pinfo = suspend_find_thread(thread);
+
+    if (!pinfo)
+        pinfo = suspend_add_thread(thread);
+
+    if (!pinfo)
+    {
+        pthread_mutex_unlock(&g_suspend_mutex);
+        return -1;
+    }
+
+    if (pinfo->suspend_count > 0)
+    {
+        ++pinfo->suspend_count;
+        pthread_mutex_unlock(&g_suspend_mutex);
+        return 0;
+    }
+
+    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 -1;
+    }
+
+    /* Waiting for suspendee response */
+    sem_wait(&pinfo->wake_sem);
+    /* Check result */
+    status = (pinfo->suspend_count > 0) ? 0 : -1;
+
+    pthread_mutex_unlock(&g_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;
+
+    if (!thread)
+        return -1;
+
+    if (!suspend_init_lock())
+        return -1;
+
+    pinfo = suspend_find_thread(thread);
+
+    if (!pinfo)
+    {
+        pthread_mutex_unlock(&g_suspend_mutex);
+        return -1;
+    }
+
+    if (pinfo->suspend_count > 1)
+    {
+        --pinfo->suspend_count;
+        pthread_mutex_unlock(&g_suspend_mutex);
+        return 0;
+    }
+
+    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 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;
+    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 port_thread_get_context(osthread_t thread, thread_context_t *context)
+{
+    int status = -1;
+    os_thread_info_t* pinfo;
+
+    if (!thread || !context)
+        return -1;
+
+    if (!suspend_init_lock())
+        return -1;
+
+    pinfo = suspend_find_thread(thread);
+
+    if (!pinfo)
+    {
+        pthread_mutex_unlock(&g_suspend_mutex);
+        return status;
+    }
+
+    if (pinfo->suspend_count > 0)
+    {
+        *context = pinfo->context;
+        status = -1;
+    }
+
+    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 port_thread_set_context(osthread_t thread, thread_context_t *context)
+{
+    int status = -1;
+    os_thread_info_t* pinfo;
+
+    if (!thread || !context)
+        return -1;
+
+    if (!suspend_init_lock())
+        return -1;
+
+    pinfo = suspend_find_thread(thread);
+
+    if (!pinfo)
+    {
+        pthread_mutex_unlock(&g_suspend_mutex);
+        return status;
+    }
+
+    if (pinfo->suspend_count > 0)
+    {
+        pinfo->context = *context;
+        status = 0;
+    }
+
+    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 */
+    }
+}

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

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_asm_em64t.asm
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_asm_em64t.asm?rev=633414&r1=633413&r2=633414&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_asm_em64t.asm (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_asm_em64t.asm Tue Mar  4 02:26:56 2008
@@ -41,11 +41,11 @@
 ; uint32 eflags;; 88h
 ; };
 ;
-; void transfer_to_regs(Registers* regs)
+; void port_transfer_to_regs(Registers* regs)
 
-PUBLIC  transfer_to_regs
+PUBLIC  port_transfer_to_regs
 
-transfer_to_regs PROC
+port_transfer_to_regs PROC
 
     mov     rdx, rcx ; regs pointer (1st param - RCX) -> RDX
 
@@ -81,7 +81,48 @@
     mov     rsp, qword ptr [rsp]     ; load new RSP
     jmp     qword ptr [rsp-88h]      ; JMP to new RIP
 
-transfer_to_regs ENDP
+port_transfer_to_regs ENDP
+
+
+; void port_longjump_stub(void)
+;
+; after returning from the called function, RSP points to the 2 argument
+; slots in the stack. Saved Registers structure pointer is (RSP + 48)
+;
+; | interrupted |
+; |  program    | <- RSP where the program was interrupted by exception
+; |-------------|
+; | 0x80 bytes  | <- preserved stack area - we will not change it
+; |-------------|
+; | return addr |
+; | from stub   | <- for using in port_transfer_to_regs as [(new RSP) - 128 - 8]
+; |-------------|
+; |    saved    |
+; |  Registers  | <- to restore register context
+; |-------------|
+; | [alignment] | <- align Regs pointer to 16-bytes boundary
+; |-------------|
+; |  pointer to |
+; |  saved Regs | <- (RSP + 48)
+; |-------------|
+; |    arg 5    | <- present even if not used
+; |-------------|
+; |    arg 4    | <- present even if not used
+; |-------------|
+; |  32 bytes   | <- 'red zone' for argument registers flushing
+; |-------------|
+; | return addr |
+; |  from 'fn'  | <- address to return to the port_longjump_stub
+; |-------------|
+
+PUBLIC  port_longjump_stub
+
+port_longjump_stub PROC
+
+    mov     rcx, qword ptr [rsp + 48] ; load RCX with the address of saved Registers
+    call    port_transfer_to_regs   ; restore context
+    ret                             ; dummy RET - unreachable
+port_longjump_stub ENDP
 
 
 _TEXT   ENDS

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_asm_ia32.asm
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_asm_ia32.asm?rev=633414&r1=633413&r2=633414&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_asm_ia32.asm (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_asm_ia32.asm Tue Mar  4 02:26:56 2008
@@ -31,11 +31,11 @@
 ; uint32 eflags; +24
 ; };
 ;
-; void transfer_to_regs(Registers* regs)
+; void port_transfer_to_regs(Registers* regs)
 
-PUBLIC  transfer_to_regs
+PUBLIC  port_transfer_to_regs
 
-transfer_to_regs PROC
+port_transfer_to_regs PROC
 
     mov     edx, dword ptr [esp+04h] ; store regs pointer to EDX
     mov     ebx, dword ptr [edx+20h] ; EIP field -> EBX
@@ -59,7 +59,44 @@
     mov     esp, dword ptr [esp+04h] ; ((new ESP - 4) -> ESP
     ret                              ; JMP by RET
 
-transfer_to_regs ENDP
+port_transfer_to_regs ENDP
+
+
+; void port_longjump_stub(void)
+;
+; after returning from the called function, EBP points to the pointer
+; to saved Registers structure
+;
+; | interrupted |
+; |  program    | <- ESP where the program was interrupted by exception
+; |-------------|
+; | return addr |
+; | from stub   | <- for using in port_transfer_to_regs
+; |-------------|
+; |    saved    |
+; |  Registers  | <- to restore register context
+; |-------------|
+; |  pointer to |
+; |  saved Regs | <- EBP
+; |-------------|
+; |  arg 5      | <-
+; |-------------|   |
+; ...............    - arguments for 'fn'
+; |-------------|   |
+; |  arg 0      | <-
+; |-------------|
+; | return addr |
+; |  from 'fn'  | <- address to return to the port_longjump_stub
+; |-------------|
+
+PUBLIC  port_longjump_stub
+
+port_longjump_stub PROC
+
+    mov     esp, ebp    ; ESP now points to the address of saved Registers
+    call    port_transfer_to_regs   ; restore context
+    ret                             ; dummy RET - unreachable
+port_longjump_stub ENDP
 
 
 _TEXT   ENDS

Copied: harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_em64t.c (from r633236, harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/em64t/nt_exception_filter.cpp)
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_em64t.c?p2=harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_em64t.c&p1=harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/em64t/nt_exception_filter.cpp&r1=633236&r2=633414&rev=633414&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/em64t/nt_exception_filter.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_em64t.c Tue Mar  4 02:26:56 2008
@@ -15,12 +15,10 @@
  *  limitations under the License.
  */
 
-#include <stdio.h>
-#include "platform_lowlevel.h"
-#include "vm_core_types.h"
+#include "port_thread.h"
 
 
-void nt_to_vm_context(PCONTEXT pcontext, Registers* regs)
+void port_thread_context_to_regs(Registers* regs, PCONTEXT pcontext)
 {
     regs->rsp = pcontext->Rsp;
     regs->rbp = pcontext->Rbp;
@@ -45,7 +43,7 @@
     regs->eflags = pcontext->EFlags;
 }
 
-void vm_to_nt_context(Registers* regs, PCONTEXT pcontext)
+void port_thread_regs_to_context(PCONTEXT pcontext, Registers* regs)
 {
     pcontext->Rsp = regs->rsp;
     pcontext->Rbp = regs->rbp;
@@ -75,28 +73,119 @@
     return (void*)pregs->rsp;
 }
 
-// Max. 4 arguments can be set up
-void regs_push_param(Registers* pregs, POINTER_SIZE_INT param, int num)
-{ // RCX, RDX, R8, R9
-    switch (num)
-    {
-    case 0:
-        pregs->rcx = param;
-        return;
-    case 1:
-        pregs->rdx = param;
-        return;
-    case 2:
-        pregs->r8 = param;
-        return;
-    case 3:
-        pregs->r9 = param;
+
+void port_longjump_stub(void);
+#define DIR_FLAG ((uint32)0x00000400)
+
+void port_set_longjump_regs(void* fn, Registers* regs, int num, ...)
+{
+    void** sp;
+    va_list ap;
+    int i;
+    size_t align;
+    void** p_pregs;
+    size_t rcount =
+        (sizeof(Registers) + sizeof(void*) - 1) / sizeof(void*);
+
+    if (!regs)
         return;
+
+    sp = (void**)regs->rsp - 16 - 1; /* preserve 128-bytes area */
+    *sp = (void*)regs->rip;
+    align = !((rcount & 1) ^ (((uint64)sp & sizeof(void*)) != 0));
+    p_pregs = sp - rcount - align - 1;
+    sp = sp - rcount;
+    *((Registers*)sp) = *regs;
+    *p_pregs = (void*)sp;
+
+    sp = p_pregs - 6 - 1;
+
+    va_start(ap, num);
+
+    if (num > 0)
+    {
+        void* arg = va_arg(ap, void*);
+        if (arg == regs)
+            regs->rcx = (uint64)(*p_pregs); /* Replace 1st arg */
+        else
+            regs->rcx = (uint64)arg;
+    }
+
+    if (num > 1)
+        regs->rdx = (uint64)va_arg(ap, void*);
+
+    if (num > 2)
+        regs->r8 = (uint64)va_arg(ap, void*);
+
+    if (num > 3)
+        regs->r9 = (uint64)va_arg(ap, void*);
+
+    for (i = 5; i <= num; i = i + 1)
+    {
+        sp[i] = va_arg(ap, void*);
     }
+
+    *sp = (void*)&port_longjump_stub;
+    regs->rsp = (uint64)sp;
+    regs->rip = (uint64)fn;
+    regs->eflags = regs->eflags & ~DIR_FLAG;
 }
 
-void regs_push_return_address(Registers* pregs, void* ret_addr)
+void port_transfer_to_function(void* fn, Registers* pregs, int num, ...)
 {
-    pregs->rsp = pregs->rsp - 8;
-    *((void**)pregs->rsp) = ret_addr;
+    void** sp;
+    va_list ap;
+    int i;
+    size_t align;
+    void** p_pregs;
+    size_t rcount =
+        (sizeof(Registers) + sizeof(void*) - 1) / sizeof(void*);
+    Registers regs;
+
+    if (!pregs)
+        return;
+
+    regs = *pregs;
+
+    sp = (void**)regs.rsp - 16 - 1; /* preserve 128-bytes area */
+    *sp = (void*)regs.rip;
+    align = !((rcount & 1) ^ (((uint64)sp & sizeof(void*)) != 0));
+    p_pregs = sp - rcount - align - 1;
+    sp = sp - rcount;
+    *((Registers*)sp) = regs;
+    *p_pregs = (void*)sp;
+
+    sp = p_pregs - 6 - 1;
+
+    va_start(ap, num);
+
+    if (num > 0)
+    {
+        void* arg = va_arg(ap, void*);
+        if (arg == pregs)
+            regs.rcx = (uint64)(*p_pregs); /* Replace 1st arg */
+        else
+            regs.rcx = (uint64)arg;
+    }
+
+    if (num > 1)
+        regs.rdx = (uint64)va_arg(ap, void*);
+
+    if (num > 2)
+        regs.r8 = (uint64)va_arg(ap, void*);
+
+    if (num > 3)
+        regs.r9 = (uint64)va_arg(ap, void*);
+
+    for (i = 5; i <= num; i = i + 1)
+    {
+        sp[i] = va_arg(ap, void*);
+    }
+
+    *sp = (void*)&port_longjump_stub;
+    regs.rsp = (uint64)sp;
+    regs.rip = (uint64)fn;
+    regs.eflags = regs.eflags & ~DIR_FLAG;
+
+    port_transfer_to_regs(&regs);
 }

Added: harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_ia32.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_ia32.c?rev=633414&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_ia32.c (added)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_ia32.c Tue Mar  4 02:26:56 2008
@@ -0,0 +1,134 @@
+/*
+ *  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 "port_thread.h"
+#define ANSI
+#include <stdarg.h>
+
+
+void port_thread_context_to_regs(Registers* regs, PCONTEXT context)
+{
+    regs->eax = context->Eax;
+    regs->ecx = context->Ecx;
+    regs->edx = context->Edx;
+    regs->edi = context->Edi;
+    regs->esi = context->Esi;
+    regs->ebx = context->Ebx;
+    regs->ebp = context->Ebp;
+    regs->eip = context->Eip;
+    regs->esp = context->Esp;
+    regs->eflags = context->EFlags;
+}
+
+void port_thread_regs_to_context(PCONTEXT context, Registers* regs)
+{
+    context->Esp = regs->esp;
+    context->Eip = regs->eip;
+    context->Ebp = regs->ebp;
+    context->Ebx = regs->ebx;
+    context->Esi = regs->esi;
+    context->Edi = regs->edi;
+    context->Eax = regs->eax;
+    context->Ecx = regs->ecx;
+    context->Edx = regs->edx;
+    context->EFlags = regs->eflags;
+}
+
+
+void port_longjump_stub(void);
+#define DIR_FLAG ((uint32)0x00000400)
+
+void port_set_longjump_regs(void* fn, Registers* regs, int num, ...)
+{
+    void** sp;
+    va_list ap;
+    int i;
+    size_t rcount =
+        (sizeof(Registers) + sizeof(void*) - 1) / sizeof(void*);
+
+    if (!regs)
+        return;
+
+    sp = (void**)regs->esp - 1;
+    *sp = (void*)regs->eip;
+    sp = sp - rcount - 1;
+    *((Registers*)(sp + 1)) = *regs;
+    *sp = (void*)(sp + 1);
+    regs->ebp = (uint32)sp;
+
+    sp = sp - num - 1;
+
+    va_start(ap, num);
+
+    for (i = 1; i <= num; i = i + 1)
+    {
+        void* arg = va_arg(ap, void*);
+
+        if (i == 1 && arg == regs)
+            sp[i] = *((void**)regs->ebp); /* Replace 1st arg */
+        else
+            sp[i] = arg;
+    }
+
+    *sp = (void*)&port_longjump_stub;
+    regs->esp = (uint32)sp;
+    regs->eip = (uint32)fn;
+    regs->eflags = regs->eflags & ~DIR_FLAG;
+}
+
+void port_transfer_to_function(void* fn, Registers* pregs, int num, ...)
+{
+    void** sp;
+    va_list ap;
+    int i;
+    size_t rcount =
+        (sizeof(Registers) + sizeof(void*) - 1) / sizeof(void*);
+    Registers regs;
+
+    if (!pregs)
+        return;
+
+    regs = *pregs;
+
+    sp = (void**)regs.esp - 1;
+    *sp = (void*)regs.eip;
+    sp = sp - rcount - 1;
+    *((Registers*)(sp + 1)) = regs;
+    *sp = (void*)(sp + 1);
+    regs.ebp = (uint32)sp;
+
+    sp = sp - num - 1;
+
+    va_start(ap, num);
+
+    for (i = 1; i <= num; i = i + 1)
+    {
+        void* arg = va_arg(ap, void*);
+
+        if (i == 1 && arg == pregs)
+            sp[i] = *((void**)regs.ebp); /* Replace 1st arg */
+        else
+            sp[i] = arg;
+    }
+
+    *sp = (void*)&port_longjump_stub;
+    regs.esp = (uint32)sp;
+    regs.eip = (uint32)fn;
+    regs.eflags = regs.eflags & ~DIR_FLAG;
+
+    port_transfer_to_regs(&regs);
+}

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

Added: 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=633414&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_os.c (added)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/thread/win/thread_os.c Tue Mar  4 02:26:56 2008
@@ -0,0 +1,371 @@
+/*
+ *  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 <apr_atomic.h>
+#include "port_thread.h"
+
+
+typedef struct os_thread_info_t os_thread_info_t;
+
+struct os_thread_info_t
+{
+    osthread_t              thread;
+    int                     suspend_count;
+    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 port_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 port_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 port_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 port_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 port_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 port_thread_get_context(osthread_t thread, 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 port_thread_set_context(osthread_t thread, 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;
+}
+

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

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=633414&r1=633413&r2=633414&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 Tue Mar  4 02:26:56 2008
@@ -17,28 +17,15 @@
 
 #include <assert.h>
 #include <apr_atomic.h>
-#if defined(LINUX)
-#include <linux/unistd.h>	// gettid()
-#endif
 #include <sched.h>		// sched_param
 #include <semaphore.h>
 #include <unistd.h>
 #include <sys/ipc.h>
 #include <sys/shm.h>
 
+#include "port_thread.h"
 #include "thread_private.h"
 
-#ifdef LINUX
-#ifdef _syscall0
-_syscall0(pid_t,gettid)
-pid_t gettid(void);
-#else
-static pid_t gettid(void)
-{
-    return (pid_t)syscall(__NR_gettid);
-}
-#endif
-#endif
 
 /**
  * Creates new thread.
@@ -174,24 +161,6 @@
 }
 
 /**
- * Calculates absolute time in future for sem_timedwait timeout.
- * @param ptime The pointer to time structure to fill
- * @param delay Desired timeout in ns; not greater than 10^9 (1s)
- */
-static inline __attribute__((always_inline))
-void get_exceed_time(struct timespec* ptime, long delay)
-{
-    clock_gettime(CLOCK_REALTIME, ptime);
-
-    ptime->tv_nsec += delay;
-    if (ptime->tv_nsec >= 1000000000L) // overflow
-    {
-        ptime->tv_nsec -= 1000000000L;
-        ++ptime->tv_sec;
-    }
-}
-
-/**
  * Queries amount of user and kernel times consumed by the thread,
  * in nanoseconds.
  *
@@ -237,481 +206,4 @@
 
     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 */
-    }
 }

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=633414&r1=633413&r2=633414&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 Tue Mar  4 02:26:56 2008
@@ -35,6 +35,7 @@
 
 #include <apr_atomic.h>
 #include <open/hythread_ext.h>
+#include "port_thread.h"
 #include "thread_private.h"
 
 extern hythread_group_t TM_DEFAULT_GROUP;
@@ -299,7 +300,7 @@
  * @return none
  */
 void VMCALL hythread_yield_other(hythread_t thread) {
-    os_thread_yield_other(thread->os_handle);
+    port_thread_yield_other(thread->os_handle);
 }
 
 /** 
@@ -520,7 +521,7 @@
 void VMCALL hythread_cancel(hythread_t thread) {
     osthread_t os_handle = thread->os_handle;
     hythread_detach(thread);
-    os_thread_cancel(os_handle);
+    port_thread_cancel(os_handle);
     os_thread_join(os_handle);
 }
 

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_thin_monitor.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_thin_monitor.c?rev=633414&r1=633413&r2=633414&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_thin_monitor.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_thin_monitor.c Tue Mar  4 02:26:56 2008
@@ -24,10 +24,11 @@
 #define LOG_DOMAIN "tm.locks"
 
 #include <open/hythread_ext.h>
-#include "thread_private.h"
 #include <apr_atomic.h>
 #include <port_atomic.h>
 #include "port_barriers.h"
+#include "port_thread.h"
+#include "thread_private.h"
 
 /** @name Thin monitors support. Implement thin-fat scheme.
  */
@@ -240,7 +241,7 @@
 
     // resume owner
     if (owner) {
-        os_thread_yield_other(owner->os_handle);
+        port_thread_yield_other(owner->os_handle);
         hythread_resume(owner);
     }
 

Modified: 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=633414&r1=633413&r2=633414&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ncai_common.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ncai_common.c Tue Mar  4 02:26:56 2008
@@ -12,6 +12,7 @@
 #include "thread_private.h"
 #include <open/ncai_thread.h>
 #include <open/jthread.h>
+#include "port_thread.h"
 
 
 /**
@@ -29,7 +30,7 @@
 
     assert(thread->os_handle);
 
-    return os_thread_suspend(thread->os_handle);
+    return port_thread_suspend(thread->os_handle);
 }
 
 /**
@@ -47,7 +48,7 @@
 
     assert(thread->os_handle);
 
-    return os_thread_resume(thread->os_handle);
+    return port_thread_resume(thread->os_handle);
 }
 
 /**
@@ -66,7 +67,7 @@
 
     assert(thread->os_handle);
 
-    return os_thread_get_suspend_count(thread->os_handle);
+    return port_thread_get_suspend_count(thread->os_handle);
 }
 
 /**
@@ -75,7 +76,7 @@
  * @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)
+IDATA VMCALL hythread_get_thread_context(hythread_t thread, thread_context_t* pcontext)
 {
     if (pcontext == NULL || thread == NULL)
         return TM_ERROR_NULL_POINTER;
@@ -85,7 +86,7 @@
 
     assert(thread->os_handle);
 
-    return os_thread_get_context(thread->os_handle, pcontext);
+    return port_thread_get_context(thread->os_handle, pcontext);
 }
 
 /**
@@ -94,7 +95,7 @@
  * @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)
+IDATA VMCALL hythread_set_thread_context(hythread_t thread, thread_context_t* pcontext)
 {
     if (pcontext == NULL || thread == NULL)
         return TM_ERROR_NULL_POINTER;
@@ -104,5 +105,5 @@
 
     assert(thread->os_handle);
 
-    return os_thread_get_context(thread->os_handle, pcontext);
+    return port_thread_get_context(thread->os_handle, pcontext);
 }

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=633414&r1=633413&r2=633414&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h Tue Mar  4 02:26:56 2008
@@ -309,21 +309,14 @@
         hythread_wrapper_t func, void *data);
 int os_thread_set_priority(osthread_t thread, int priority);
 osthread_t os_thread_current();
-int os_thread_cancel(osthread_t);
 int os_thread_free(osthread_t os_thread);
 void os_thread_exit(IDATA status);
 int os_thread_join(osthread_t os_thread);
-void os_thread_yield_other(osthread_t);
 int os_get_thread_times(osthread_t os_thread, int64* pkernel, int64* puser);
 
 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
 }



Mime
View raw message