harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wjwashb...@apache.org
Subject svn commit: r520478 [2/2] - in /harmony/enhanced/drlvm/trunk: build/make/components/vm/ build/make/targets/ vm/em/src/ vm/include/open/ vm/tests/kernel/java/lang/ vm/tests/unit/thread/ vm/thread/src/ vm/thread/src/linux/ vm/thread/src/win/ vm/vmcore/in...
Date Tue, 20 Mar 2007 16:55:20 GMT
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?view=diff&rev=520478&r1=520477&r2=520478
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h Tue Mar 20 09:55:17 2007
@@ -33,6 +33,10 @@
 #include <assert.h>
 #include "apr_thread_ext.h"
 
+#ifdef __linux__
+#include <pthread.h>
+#endif // __linux__
+
 // temporary remove logging
 #define TRACE(a) //printf a; printf("\n")
 //#include "clog.h"
@@ -101,37 +105,14 @@
 #define tm_self_tls (hythread_self())
 #endif
 
-/**
- * get_local_pool() function return apr pool associated with the current thread.
- * the memory could be allocated without lock using this pool
- * deallocation should be done in the same thread, otherwise 
- * local_pool_cleanup_register() should be called
- */
-apr_pool_t* get_local_pool();
- 
-/**
- * local_pool_cleanup_register() synchronously register the cleanup function.
- * It should be called to request cleanup in thread local pool, from other thread
- * Usage scenario:
- * IDATA hymutex_destroy (tm_mutex_t *mutex) {
- *        apr_pool_t *pool = apr_thread_mutex_pool_get ((apr_thread_mutex_t*)mutex);
- *        if (pool != get_local_pool()) {
- *              return local_pool_cleanup_register(hymutex_destroy, mutex);
- *      }
- *      apr_thread_mutex_destroy(mutex);
- *  return TM_ERROR_NONE;
- * }
- *  
- */
-IDATA local_pool_cleanup_register(void* func, void* data); 
-
-
 
-// Direct mappings to porting layer / APR 
-#define HyCond apr_thread_cond_t
-#define HyMutex apr_thread_mutex_t 
-//#define tm_rwlock_t apr_rwlock_t 
-//#define _tm_threadkey_t apr_threadkey_t 
+#ifdef __linux__
+#define osthread_t pthread_t
+#elif _WIN32
+#define osthread_t HANDLE
+#else // !_WIN32 && !__linux__
+#error "threading is only supported on __linux__ or _WIN32"
+#endif // !_WIN32 && !__linux__
 
 
 extern hythread_group_t TM_DEFAULT_GROUP;
@@ -223,7 +204,7 @@
     /**
      * Handle to OS thread.
      */
-    apr_thread_t *os_handle;    
+    osthread_t os_handle;
         
     /**
      * Placeholder for any data to be associated with this thread.
@@ -262,7 +243,7 @@
     /**
      * Current conditional variable thread is waiting on (used for interrupting)
      */
-    hycond_t current_condition;
+    hycond_t *current_condition;
 
 // State
 
@@ -299,11 +280,6 @@
     IDATA thread_id;
 
     /**
-     * Memory pool in with this thread allocated
-     */
-    apr_pool_t *pool;
-
-    /**
      * APR thread attributes
      */
     apr_threadattr_t *apr_attrs;
@@ -485,12 +461,6 @@
     int notify_flag;
 
     /**
-     * monitor sub pool
-     * will be destroyed by monitor_destroy()
-     */
-    apr_pool_t *pool;
-
-    /**
      * Owner thread ID. 
      */
     IDATA thread_id;
@@ -553,12 +523,6 @@
      * Mutex associated with the semaphore data.
      */
     hymutex_t mutex;         
-
-    /**
-     * semaphore sub pool
-     * will be destroyed by sem_destroy()
-     */
-    apr_pool_t *pool;     
 } HySemaphore;
 
 // Global variables 
@@ -620,7 +584,7 @@
 IDATA release_start_lock(void);
 
 IDATA thread_sleep_impl(I_64 millis, IDATA nanos, IDATA interruptable);
-IDATA condvar_wait_impl(hycond_t cond, hymutex_t mutex, I_64 ms, IDATA nano, IDATA interruptable);
+IDATA condvar_wait_impl(hycond_t *cond, hymutex_t *mutex, I_64 ms, IDATA nano, IDATA interruptable);
 IDATA monitor_wait_impl(hythread_monitor_t mon_ptr, I_64 ms, IDATA nano, IDATA interruptable);
 IDATA thin_monitor_wait_impl(hythread_thin_monitor_t *lockword_ptr, I_64 ms, IDATA nano,
IDATA interruptable);
 IDATA sem_wait_impl(hysem_t sem, I_64 ms, IDATA nano, IDATA interruptable);
@@ -653,6 +617,20 @@
 void thread_start_count();
 void thread_end_count();
 
+/*
+ * portability functions, private for thread module
+ */
+int os_thread_create(osthread_t* phandle, UDATA stacksize, UDATA priority,
+        int (VMAPICALL *func)(void*), 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_join(osthread_t);
+void os_thread_exit(int status);
+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);
 
 #ifdef __cplusplus
 }

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_monitors.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_monitors.c?view=diff&rev=520478&r1=520477&r2=520478
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_monitors.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_monitors.c Tue Mar 20 09:55:17 2007
@@ -63,11 +63,11 @@
         if (status != TM_ERROR_NONE) return status;
     }
     
-    status =hymutex_lock(jvmti_monitor_table_lock);
+    status =hymutex_lock(&jvmti_monitor_table_lock);
     if (status != TM_ERROR_NONE) return status;
     *mon_ptr = array_add(jvmti_monitor_table, monitor);
 
-    status =hymutex_unlock(jvmti_monitor_table_lock);
+    status =hymutex_unlock(&jvmti_monitor_table_lock);
     if (status != TM_ERROR_NONE) return status;
     if (!(*mon_ptr)) return TM_ERROR_OUT_OF_MEMORY;
 
@@ -93,10 +93,10 @@
             return status;
     }
     
-    status =hymutex_lock(jvmti_monitor_table_lock);
+    status =hymutex_lock(&jvmti_monitor_table_lock);
     if (status != TM_ERROR_NONE) return status;
     array_delete(jvmti_monitor_table, (UDATA)mon_ptr);
-    status =hymutex_unlock(jvmti_monitor_table_lock);
+    status =hymutex_unlock(&jvmti_monitor_table_lock);
     return status;
 }
 

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_timing.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_timing.c?view=diff&rev=520478&r1=520477&r2=520478
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_timing.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_timing.c Tue Mar 20 09:55:17 2007
@@ -62,6 +62,7 @@
 IDATA VMCALL jthread_get_thread_cpu_time(jthread java_thread, jlong *nanos_ptr) {
 
     hythread_t tm_native_thread;
+    int64 kernel_time;
     assert(nanos_ptr);
 
     if (NULL == java_thread) {
@@ -70,8 +71,7 @@
         tm_native_thread = vm_jthread_get_tm_data(java_thread);
     }
 
-    return CONVERT_ERROR(apr_get_thread_time(tm_native_thread->os_handle,
-        (apr_int64_t*) nanos_ptr));
+    return hythread_get_thread_times(tm_native_thread, &kernel_time, nanos_ptr);
 }
 
 /**
@@ -92,13 +92,13 @@
 IDATA VMCALL jthread_get_thread_user_cpu_time(jthread java_thread, jlong *nanos_ptr) {
 
     hythread_t tm_native_thread;
-    apr_time_t kernel_time;
-    apr_time_t user_time;
+    int64 kernel_time;
+    int64 user_time;
 
     assert(java_thread);
     assert(nanos_ptr);
     tm_native_thread = vm_jthread_get_tm_data(java_thread);
-    apr_thread_times(tm_native_thread->os_handle, &user_time, &kernel_time);
+    hythread_get_thread_times(tm_native_thread, &kernel_time, &user_time);
     *nanos_ptr = user_time;
 
     return TM_ERROR_NONE;

Added: harmony/enhanced/drlvm/trunk/vm/thread/src/win/os_condvar.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/win/os_condvar.c?view=auto&rev=520478
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/win/os_condvar.c (added)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/win/os_condvar.c Tue Mar 20 09:55:17 2007
@@ -0,0 +1,182 @@
+/*
+ *  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.
+ */
+
+/**
+ * @file os_condvar.c
+ * @brief Custom queue-based condition variable implementation.
+ * @detailed Custom implementation is needed on Windows, because it lacks
+ *      the suitable condition variable synchronization object.
+ */
+
+#include <open/hythread_ext.h>
+#include "thread_private.h"
+
+static void _enqueue (hycond_t *cond, struct waiting_node *node)
+{
+     node->next = &cond->dummy_node;
+     node->prev = cond->dummy_node.prev;
+     node->prev->next = node;
+     cond->dummy_node.prev = node;
+}
+
+static int _remove_from_queue (hycond_t *cond, struct waiting_node *node)
+{
+    if (node->next == NULL || node->prev == NULL) {
+        // already dequeued (by signal)
+        return -1;
+    }
+    node->prev->next = node->next;
+    node->next->prev = node->prev;
+    node->next = NULL;
+    node->prev = NULL;
+    return 0;
+}
+
+// returns NULL if queue is empty
+static struct waiting_node * _dequeue (hycond_t *cond)
+{
+    struct waiting_node *node;
+    if (cond->dummy_node.next == &cond->dummy_node) {
+        // the queue is empty
+        return NULL;
+    }
+    node = cond->dummy_node.next;
+    _remove_from_queue(cond,node);
+    return node;
+}
+
+/**
+ * waits on a condition variable, directly using OS interfaces.
+ *
+ * This function does not implement interruptability and thread state
+ * functionality, thus the caller of this function have to handle it.
+ */
+int os_cond_timedwait(hycond_t *cond, hymutex_t *mutex, I_64 ms, IDATA nano)
+{
+    int r = 0;
+    struct waiting_node node;
+    DWORD res;
+    DWORD timeout;
+    if (!ms && !nano) {
+        timeout = INFINITE;
+    } else {
+        timeout = (DWORD)ms + (nano ? 1:0);
+    }
+
+    // NULL attributes, manual reset, initially unsignalled, NULL name
+    node.event = CreateEvent(NULL, TRUE, FALSE, NULL);
+    hymutex_lock(&cond->queue_mutex);
+    _enqueue(cond, &node);
+    hymutex_unlock(&cond->queue_mutex);
+
+    // release mutex and wait for signal
+    hymutex_unlock(mutex);
+
+    res = WaitForSingleObject(node.event, timeout);
+    if (res != WAIT_OBJECT_0) {
+        if (res == WAIT_TIMEOUT)
+            r = TM_ERROR_TIMEOUT;
+        else
+            r = (int)GetLastError();
+    }
+
+    // re-acquire mutex associated with condition variable
+    hymutex_lock(mutex);
+
+    hymutex_lock(&cond->queue_mutex);
+    _remove_from_queue(cond, &node);
+    CloseHandle(node.event);
+    hymutex_unlock(&cond->queue_mutex);
+
+    return r;
+}
+
+/** @name Conditional variable
+ */
+//@{
+
+/**
+ * Creates and initializes condition variable.
+ *
+ * @param[in] cond the address of the condition variable.
+ * @return 0 on success, non-zero otherwise.
+ */
+IDATA VMCALL hycond_create (hycond_t *cond) {
+    cond->dummy_node.next = cond->dummy_node.prev = &cond->dummy_node;
+    hymutex_create(&cond->queue_mutex, APR_THREAD_MUTEX_NESTED);
+    return 0;
+}
+
+/**
+ * Signals a single thread that is blocking on the given condition variable to
+ * wake up.
+ *
+ * @param[in] cond the condition variable on which to produce the signal.
+ * @sa apr_thread_cond_signal()
+ */
+IDATA VMCALL hycond_notify (hycond_t *cond) {
+    int r = 0;
+    DWORD res;
+    struct waiting_node *node;
+
+    hymutex_lock(&cond->queue_mutex);
+    node = _dequeue(cond);
+    if (node != NULL) {
+        res = SetEvent(node->event);
+        if (res == 0) {
+             r = (int)GetLastError();
+        }
+    }
+    hymutex_unlock(&cond->queue_mutex);
+    return r;
+}
+
+/**
+ * Signals all threads blocking on the given condition variable.
+ *
+ * @param[in] cond the condition variable on which to produce the broadcast.
+ * @sa apr_thread_cond_broadcast()
+ */
+IDATA VMCALL hycond_notify_all (hycond_t *cond) {
+    int r = 0;
+    DWORD res;
+    struct waiting_node *node;
+
+    hymutex_lock(&cond->queue_mutex);
+    for (node = _dequeue(cond); node != NULL; node = _dequeue(cond)) {
+        res = SetEvent(node->event);
+        if (res == 0) {
+            r = GetLastError();
+        }
+    }
+    hymutex_unlock(&cond->queue_mutex);
+    return r;
+}
+
+/**
+ * Destroys the condition variable and releases the associated memory.
+ *
+ * @param[in] cond the condition variable to destroy
+ * @sa apr_thread_cond_destroy()
+ */
+IDATA VMCALL hycond_destroy (hycond_t *cond) {
+    assert(cond->dummy_node.next == &cond->dummy_node
+            && "destroying condition variable with active waiters");
+    return hymutex_destroy(&cond->queue_mutex);
+}
+
+//@}

Added: harmony/enhanced/drlvm/trunk/vm/thread/src/win/os_mutex.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/win/os_mutex.c?view=auto&rev=520478
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/win/os_mutex.c (added)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/win/os_mutex.c Tue Mar 20 09:55:17 2007
@@ -0,0 +1,103 @@
+/*
+ *  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.
+ */
+
+/**
+ * @file thread_native_mutex.c
+ * @brief hymutex binding to Win32 critical sections
+ */
+
+#include "thread_private.h"
+#include <open/hythread_ext.h>
+
+
+/** @name Mutex
+ *
+ */
+//@{
+
+/**
+ * Initializes a mutex.
+ *
+ * A memory for mutex must be preallocated.
+ *
+ * @param[in] mutex the address of the mutex to be initialized
+ * @param[in] flags Or'ed value of:
+ * <PRE>
+ *           APR_THREAD_MUTEX_DEFAULT   platform-optimal lock behavior.
+ *           APR_THREAD_MUTEX_NESTED    enable nested (recursive) locks.
+ *           APR_THREAD_MUTEX_UNNESTED  disable nested locks (non-recursive).
+ * </PRE>
+ */
+IDATA VMCALL hymutex_create (hymutex_t *mutex, UDATA flags) {
+    int r = 0;
+    if (flags & APR_THREAD_MUTEX_UNNESTED) {
+        assert(!"not implemented");
+        return -1;
+    }
+    InitializeCriticalSection(mutex);
+    return r;
+}
+
+/**
+ * Acquires the lock for the given mutex. If the mutex is already locked,
+ * the current thread will be put to sleep until the lock becomes available.
+ *
+ * @param[in] mutex the mutex on which to acquire the lock.
+ * @sa apr_thread_mutex_lock()
+ */
+IDATA VMCALL hymutex_lock(hymutex_t *mutex) {
+    EnterCriticalSection(mutex);
+    return 0;
+}
+
+/**
+ * Attempts to acquire the lock for the given mutex.
+ *
+ * @param[in] mutex the mutex on which to attempt the lock acquiring.
+ * @sa apr_thread_mutex_trylock()
+ */
+IDATA VMCALL hymutex_trylock (hymutex_t *mutex) {
+    int r;
+    r = TryEnterCriticalSection(mutex);
+    // Return code is non-zero on success
+    if (r == 0) return TM_ERROR_EBUSY;
+    return 0;
+}
+
+/**
+ * Releases the lock for the given mutex.
+ *
+ * @param[in] mutex the mutex from which to release the lock.
+ * @sa apr_thread_mutex_unlock()
+ */
+IDATA VMCALL hymutex_unlock (hymutex_t *mutex) {
+    LeaveCriticalSection(mutex);
+    return 0;
+}
+
+/**
+ * Destroys the mutex.
+ *
+ * @param[in] mutex the mutex to destroy.
+ * @sa apr_thread_mutex_destroy()
+ */
+IDATA VMCALL hymutex_destroy (hymutex_t *mutex) {
+    DeleteCriticalSection(mutex);
+    return 0;
+}
+
+//@}

Added: harmony/enhanced/drlvm/trunk/vm/thread/src/win/os_thread.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/win/os_thread.c?view=auto&rev=520478
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/win/os_thread.c (added)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/win/os_thread.c Tue Mar 20 09:55:17 2007
@@ -0,0 +1,189 @@
+/*
+ *  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 "thread_private.h"
+
+/**
+ * Creates new thread.
+ *
+ * @param[out] handle on success, thread handle is stored in memory pointed by handle
+ * @param stacksize size of stack to be allocated for a new thread
+ * @param priority priority of a new thread
+ * @param func function to be started on a new thread
+ * @param data value to be passed to a function started on a new thread
+ *
+ * @return 0 on success, TM_ERROR_OUT_OF_MEMORY if system is thread cannot be created because
+ *         of insufficient memory, system error otherwise.
+ */
+int os_thread_create(/* out */osthread_t* phandle, UDATA stacksize, UDATA priority,
+        int (VMAPICALL *func)(void*), void *data)
+{
+    HANDLE handle = (HANDLE)_beginthreadex(NULL, stacksize, (unsigned(__stdcall *)(void*))func,
data, 0, NULL);
+    if (handle) {
+        *phandle = handle;
+        if (priority)
+            SetThreadPriority(handle, priority);
+        return 0;
+    } else {
+        int error = GetLastError();
+        if (error == ERROR_OUTOFMEMORY)
+            return TM_ERROR_OUT_OF_MEMORY;
+        return error;
+    }
+}
+
+/**
+ * Adjusts priority of the running thread.
+ *
+ * @param thread        handle of thread
+ * @param priority      new priority value
+ *
+ * @return              0 on success, system error otherwise
+ */
+int os_thread_set_priority(osthread_t os_thread, int priority)
+{
+    if (SetThreadPriority(os_thread, (int)priority)) {
+        return 0;
+    } else {
+        return GetLastError();
+    }
+}
+
+/**
+ * Returns os handle of the current thread.
+ *
+ * @return current thread handle on success, NULL on error
+ */
+osthread_t os_thread_current()
+{
+    HANDLE hproc = GetCurrentProcess();
+    HANDLE hthread = GetCurrentThread();
+    if (!DuplicateHandle(hproc, hthread,
+                         hproc, &hthread, 0, FALSE,
+                         DUPLICATE_SAME_ACCESS)) {
+        return NULL;
+    }
+    return hthread;
+}
+
+/**
+ * Terminates the os thread.
+ */
+int os_thread_cancel(osthread_t os_thread)
+{
+    if (TerminateThread(os_thread, 0))
+        return 0;
+    else
+        return GetLastError();
+}
+
+/**
+ * Joins the os thread.
+ *
+ * @param os_thread     thread handle
+ *
+ * @return              0 on success, systerm error otherwise
+ */
+int os_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;
+}
+
+/**
+ * Causes the current thread to stop execution.
+ *
+ * @param status        returns status of a thread
+ */
+void os_thread_exit(int status)
+{
+    ExitThread(status);
+}
+
+/**
+ * Causes the other thread to have a memory barrier by suspending
+ * and resuming it.
+ */
+void os_thread_yield_other(osthread_t os_thread)
+{
+    static CRITICAL_SECTION yield_other_mutex;
+    static int initialized = 0;
+    if (!initialized) {
+        // Critical section should be initialized only once,
+        // do nothing in case someone else already initialized it.
+        if (apr_atomic_cas32((volatile uint32*)&initialized, 1, 0) == 0) {
+            InitializeCriticalSectionAndSpinCount(&yield_other_mutex, 400);
+        }
+    }
+
+    // FIXME: should not use yield_other_mutex until it is guaranteed to be initialized
+
+    /*
+     * Synchronization is needed to avoid cyclic (mutual) suspension problem.
+     * Accordingly to MSDN, it is possible on multiprocessor box that
+     * 2 threads suspend each other and become deadlocked.
+     */
+    EnterCriticalSection(&yield_other_mutex);
+    if (SuspendThread(os_thread) != -1) {
+        /* suspended successfully, so resume it back. */
+        ResumeThread(os_thread);
+    }
+    LeaveCriticalSection(&yield_other_mutex);
+}
+
+/**
+ * Queries amount of user and kernel times consumed by the thread,
+ * in nanoseconds.
+ *
+ * @param os_thread     thread handle
+ * @param[out] pkernel  a pointer to a variable to store kernel time to
+ * @param[out] puser    a pointer to a variable to store user time to
+ *
+ * @return      0 on success, system error otherwise
+ */
+int os_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();
+}

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h?view=diff&rev=520478&r1=520477&r2=520478
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_internal.h Tue Mar 20 09:55:17 2007
@@ -155,6 +155,7 @@
         // TI event thread data
         hythread_t event_thread;
         hycond_t event_cond;
+        int event_cond_initialized;
 
         DebugUtilsTI();
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti.cpp?view=diff&rev=520478&r1=520477&r2=520478
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti.cpp Tue Mar 20 09:55:17 2007
@@ -261,7 +261,7 @@
     error_code = newenv->allocate_extension_event_callbacks_table();
     if (error_code != JVMTI_ERROR_NONE)
     {
-        hymutex_destroy(newenv->lock);
+        hymutex_destroy(&newenv->lock);
         _deallocate((unsigned char *)newenv);
         *env = NULL;
         return error_code;
@@ -309,7 +309,7 @@
 
 DebugUtilsTI::DebugUtilsTI() :
     event_thread(NULL),
-    event_cond(NULL),
+    event_cond_initialized(0),
     agent_counter(1),
     access_watch_list(NULL),
     modification_watch_list(NULL),

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_capability.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_capability.cpp?view=diff&rev=520478&r1=520477&r2=520478
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_capability.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_capability.cpp Tue Mar 20 09:55:17
2007
@@ -402,14 +402,13 @@
     if (removed_caps.can_tag_objects) {
         // clear tags on relinquishing can_tag_objects capability
         ti_env = reinterpret_cast<TIEnv *>(env);
-        assert(ti_env->lock);
-        hymutex_lock(ti_env->lock);
+        hymutex_lock(&ti_env->lock);
         if (ti_env->tags) {
             ti_env->tags->clear();
             delete ti_env->tags;
             ti_env->tags = NULL;
         }
-        hymutex_unlock(ti_env->lock);
+        hymutex_unlock(&ti_env->lock);
 
         ti->reset_global_capability(DebugUtilsTI::TI_GC_ENABLE_TAG_OBJECTS);
     }

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp?view=diff&rev=520478&r1=520477&r2=520478
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp Tue Mar 20 09:55:17 2007
@@ -2268,16 +2268,14 @@
     hymutex_t event_mutex;
     UNREF IDATA stat = hymutex_create(&event_mutex, TM_MUTEX_NESTED);
     assert(stat == TM_ERROR_NONE);
-    hycond_t event_cond;
-    stat = hycond_create(&event_cond);
+    stat = hycond_create(&ti->event_cond);
     assert(stat == TM_ERROR_NONE);
-    ti->event_cond = event_cond;
 
     // event thread loop
     while(true) {
-        hymutex_lock(event_mutex);
-        hycond_wait(event_cond, event_mutex);
-        hymutex_unlock(event_mutex);
+        hymutex_lock(&event_mutex);
+        hycond_wait(&ti->event_cond, &event_mutex);
+        hymutex_unlock(&event_mutex);
 
         if(!ti->event_thread) {
             // event thread is NULL,
@@ -2290,9 +2288,9 @@
     }
 
     // release wait loop environment
-    stat = hymutex_destroy(event_mutex);
+    stat = hymutex_destroy(&event_mutex);
     assert(stat == TM_ERROR_NONE);
-    stat = hycond_destroy(event_cond);
+    stat = hycond_destroy(&ti->event_cond);
     assert(stat == TM_ERROR_NONE);
 
     return 0;
@@ -2333,14 +2331,8 @@
         return;
     }
 
-    // getting condition
-    hycond_t event_cond = ti->event_cond;
-    ti->event_thread = NULL;
-    ti->event_cond = NULL;
-
     // notify event thread
-    assert(event_cond);
-    UNREF IDATA stat = hycond_notify(event_cond);
+    UNREF IDATA stat = hycond_notify(&ti->event_cond);
     assert(stat == TM_ERROR_NONE);
     return;
 }
@@ -2349,12 +2341,11 @@
 jvmti_notify_data_dump_request()
 {
     DebugUtilsTI *ti = VM_Global_State::loader_env->TI;
-    if( !ti->event_thread || !ti->event_cond ) {
+    if( !ti->event_thread) {
         // nothing to do
         return;
     }
-    assert(ti->event_cond);
-    UNREF IDATA stat = hycond_notify(ti->event_cond);
+    UNREF IDATA stat = hycond_notify(&ti->event_cond);
     assert(stat == TM_ERROR_NONE);
     return;
 }

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_heap.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_heap.cpp?view=diff&rev=520478&r1=520477&r2=520478
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_heap.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_heap.cpp Tue Mar 20 09:55:17 2007
@@ -124,12 +124,11 @@
         return JVMTI_ERROR_INVALID_OBJECT;
 
     if (ti_env->tags == NULL) {
-        assert(ti_env->lock);
-        hymutex_lock(ti_env->lock);
+        hymutex_lock(&ti_env->lock);
         if (ti_env->tags == NULL) {
             ti_env->tags = new TITags;
         }
-        hymutex_unlock(ti_env->lock);
+        hymutex_unlock(&ti_env->lock);
     }
 
     if (ti_env->tags == NULL) {

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/lock_manager.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/lock_manager.cpp?view=diff&rev=520478&r1=520477&r2=520478
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/lock_manager.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/lock_manager.cpp Tue Mar 20 09:55:17
2007
@@ -36,25 +36,25 @@
 
 Lock_Manager::~Lock_Manager()
 {
-    UNREF IDATA stat = hymutex_destroy (lock);
+    UNREF IDATA stat = hymutex_destroy (&lock);
     assert(stat==TM_ERROR_NONE);
 }
 
 void Lock_Manager::_lock()
 {
-    UNREF IDATA stat = hymutex_lock(lock);
+    UNREF IDATA stat = hymutex_lock(&lock);
     assert(stat==TM_ERROR_NONE);
 }
 
 bool Lock_Manager::_tryLock()
 {     
-    IDATA stat = hymutex_trylock(lock);
+    IDATA stat = hymutex_trylock(&lock);
     return stat==TM_ERROR_NONE;    
 }
 
 void Lock_Manager::_unlock()
 {
-    UNREF IDATA stat = hymutex_unlock(lock);
+    UNREF IDATA stat = hymutex_unlock(&lock);
     assert(stat==TM_ERROR_NONE);
 }
 
@@ -97,6 +97,6 @@
 
 bool Lock_Manager::_lock_enum_or_null(bool UNREF return_null_on_fail)
 {
-    IDATA stat = hymutex_lock(lock);
+    IDATA stat = hymutex_lock(&lock);
     return stat==TM_ERROR_NONE;
 }



Mime
View raw message