You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2006/08/23 18:49:21 UTC
svn commit: r434076 [11/18] - in /incubator/harmony/enhanced/drlvm/trunk:
build/make/components/ build/make/components/vm/ build/make/targets/
build/patches/lnx/ build/patches/lnx/APR/ build/patches/lnx/APR/threadproc/
build/patches/lnx/APR/threadproc/...
Added: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_thin_monitor.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_thin_monitor.c?rev=434076&view=auto
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_thin_monitor.c (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_thin_monitor.c Wed Aug 23 09:48:41 2006
@@ -0,0 +1,700 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Artem Aliev
+ * @version $Revision: 1.1.2.20 $
+ */
+
+/**
+ * @file thread_native_thin_monitor.c
+ * @brief Hythread thin monitors related functions
+ */
+
+#undef LOG_DOMAIN
+#define LOG_DOMAIN "tm.locks"
+
+#include <open/hythread_ext.h>
+#include <open/thread_externals.h>
+#include "thread_private.h"
+#include <apr_atomic.h>
+#include <port_atomic.h>
+
+/** @name Thin monitors support. Implement thin-fat scheme.
+ */
+//@{
+
+/*
+ * 32bit lock word
+ * |0|------15bit-------|--5bit--|1bit|--10bit------|
+ * thin lock -^ threadID (owner) recursion ^ hashcode
+ * |
+ * reservation bit (0 - reserved)
+ * inflated lock:
+ * |1|------------- 20bit -------|----11bit-----|
+ * fat lock -^ fat lock id
+ */
+
+// lockword operations
+#define THREAD_ID(lockword) (lockword >> 16)
+#define IS_FAT_LOCK(lockword) (lockword >> 31)
+#define FAT_LOCK_ID(lockword) ((lockword << 1) >> 12)
+// lock reservation support
+#define RESERVED_BITMASK ((1<<10))
+#define IS_RESERVED(lockword) (0==(lockword & RESERVED_BITMASK))
+
+#define RECURSION(lockword) ((lockword >> 11) & 31)
+#define RECURSION_INC(lockword_ptr, lockword) (*lockword_ptr= lockword + (1<<11))
+#define RECURSION_DEC(lockword_ptr, lockword) (*lockword_ptr=lockword - (1<<11))
+#define MAX_RECURSION 31
+
+IDATA owns_thin_lock(hythread_t thread, IDATA lockword) {
+ IDATA this_id = thread->thread_id;
+ assert(!IS_FAT_LOCK(lockword));
+ return THREAD_ID(lockword) == this_id;
+}
+
+void set_fat_lock_id(hythread_thin_monitor_t *lockword_ptr, IDATA monitor_id) {
+ IDATA lockword = *lockword_ptr;
+#ifdef LOCK_RESERVATION
+ assert(!IS_RESERVED(lockword));
+#endif
+ lockword&=0x7FF;
+ lockword|=(monitor_id << 11) | 0x80000000;
+ *lockword_ptr=lockword;
+ apr_memory_rw_barrier();
+
+}
+
+IDATA is_fat_lock(hythread_thin_monitor_t lockword) {
+ return IS_FAT_LOCK(lockword);
+}
+
+//forward decalration
+hythread_monitor_t locktable_get_fat_monitor(IDATA lock_id);
+IDATA locktable_put_fat_monitor(hythread_monitor_t fat_monitor);
+hythread_monitor_t locktable_delete_entry(int lock_id);
+hythread_monitor_t inflate_lock(hythread_thin_monitor_t *lockword_ptr);
+
+//DEBUG INFO BLOCK
+//char *vm_get_object_class_name(void* ptr);
+int unreserve_count=0;
+int inflate_contended=0;
+int inflate_waited=0;
+int unreserve_count_self=0;
+int inflate_count=0;
+int fat_lock2_count = 0;
+int init_reserve_cout = 0;
+int cas_cout = 0;
+int res_lock_count = 0;
+
+#ifdef LOCK_RESERVATION
+
+extern hymutex_t TM_LOCK;
+/*
+ * Unreserves the lock already owned by this thread
+ */
+void unreserve_self_lock(IDATA* lockword_ptr) {
+ IDATA lockword = *lockword_ptr;
+ IDATA lockword_new;
+ TRACE(("unreserve self_id %d lock owner %d", hythread_get_id(hythread_self()), THREAD_ID(lockword)));
+ assert(hythread_get_id(hythread_self()) == THREAD_ID(lockword));
+ assert (!IS_FAT_LOCK(*lockword_ptr));
+ assert (IS_RESERVED(lockword));
+ TRACE(("Unreaerve self %d \n", ++unreserve_count_self/*, vm_get_object_class_name(lockword_ptr-1)*/));
+
+ // Set reservation bit to 1 and reduce recursion count
+ lockword_new = (lockword | RESERVED_BITMASK);
+ if (RECURSION(lockword_new) != 0) {
+ RECURSION_DEC(lockword_ptr, lockword_new);
+ } else {
+ lockword_new = lockword_new & 0x0000ffff;
+ *lockword_ptr =lockword_new;
+ }
+ assert(!IS_RESERVED(*lockword_ptr));
+ TRACE(("unreserved self"));
+}
+
+/*
+ * Used lockword
+ */
+IDATA unreserve_lock(IDATA* lockword_ptr) {
+ IDATA lockword = *lockword_ptr;
+ IDATA lockword_new;
+ IDATA lock_id = THREAD_ID(lockword);
+ hythread_t owner;
+ IDATA status;
+ // trylock used to prevent cyclic suspend deadlock
+ // the java_monitor_enter calls safe_point between attempts.
+ status = hymutex_trylock(TM_LOCK);
+ if(status !=TM_ERROR_NONE) {
+ return status;
+ }
+ owner = hythread_get_thread(lock_id);
+ TRACE(("Unreaserve other %d \n", ++unreserve_count/*, vm_get_object_class_name(lockword_ptr-1)*/));
+ lockword = * lockword_ptr;
+ if(!IS_RESERVED(lockword)) {
+ hymutex_unlock(TM_LOCK);
+ return TM_ERROR_NONE;
+ }
+ // suspend owner
+ if(owner) {
+ assert(owner);
+ assert(hythread_get_id(owner) == lock_id);
+ assert(owner != hythread_self());
+ hythread_suspend_other(owner);
+ }
+ // prepare new unreserved lockword and try to CAS it with old one.
+ while (IS_RESERVED(lockword)) {
+ assert (!IS_FAT_LOCK(lockword));
+ TRACE(("unreserving lock"));
+ lockword_new = (lockword | RESERVED_BITMASK);
+ if (RECURSION(lockword) != 0) {
+ assert(RECURSION(lockword) > 0);
+ assert(RECURSION(lockword_new) > 0);
+ RECURSION_DEC(&lockword_new, lockword_new);
+ } else {
+ lockword_new = lockword_new & 0x0000ffff;
+ }
+ if(lockword == apr_atomic_cas32 (((volatile apr_uint32_t*) lockword_ptr),
+ (apr_uint32_t) lockword_new, lockword)) {
+ TRACE(("unreserved lock"));
+ break;
+ }
+ lockword = *lockword_ptr;
+ }
+
+ // resume owner
+ if(owner) {
+ apr_thread_yield_other(owner->os_handle);
+ hythread_resume(owner);
+ }
+
+ status = hymutex_unlock(TM_LOCK);
+ assert(!IS_RESERVED(*lockword_ptr));
+ return status;
+}
+#else
+IDATA unreserve_lock(IDATA* lockword_ptr) {
+ return TM_ERROR_NONE;
+}
+#endif
+
+/**
+ * Initializes a thin monitor at the given address.
+ * Thin monitor is a version of monitor which is optimized for space and
+ * single-threaded usage.
+ *
+ * @param[in] lockword_ptr monitor addr
+ */
+IDATA hythread_thin_monitor_create(hythread_thin_monitor_t *lockword_ptr) {
+ //clear anithing but hashcode
+ // 000000000000000000011111111111
+ *lockword_ptr = *lockword_ptr & 0x3FF;
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Attempts to lock thin monitor.
+ * If the monitor is already locked, this call returns immediately with TM_BUSY.
+ *
+ * @param[in] lockword_ptr monitor addr
+ */
+IDATA hythread_thin_monitor_try_enter(hythread_thin_monitor_t *lockword_ptr) {
+ IDATA lockword;
+ // warkaround strange intel compiler bug
+ #if defined (__INTEL_COMPILER) && defined (LINUX)
+ volatile
+ #endif
+ IDATA this_id = tm_self_tls->thread_id;
+ IDATA lock_id;
+ IDATA status;
+ hythread_monitor_t fat_monitor;
+ int UNUSED i;
+ assert (!hythread_is_suspend_enabled());
+ assert((UDATA)lockword_ptr > 4);
+ assert(tm_self_tls);
+
+ lockword = *lockword_ptr;
+ lock_id = THREAD_ID(lockword);
+ //TRACE(("try lock %x %d", this_id, RECURSION(lockword)));
+
+ // Check if the lock is already reserved or owned by this thread
+ if (lock_id == this_id) {
+ if (RECURSION(lockword) == MAX_RECURSION) {
+ //inflate lock in case of recursion overflow
+ fat_monitor =inflate_lock(lockword_ptr);
+ return hythread_monitor_try_enter(fat_monitor);
+ //break FAT_LOCK;
+ } else {
+ TRACE(("try lock %x count:%d", this_id, res_lock_count++));
+ // increase recursion
+ RECURSION_INC(lockword_ptr, lockword);
+ return TM_ERROR_NONE;
+ }
+ }
+
+ // Fast path didn't work, someoneelse is holding the monitor (or it isn't reserved yet):
+
+ // DO SPIN FOR A WHILE, this will decrease the number of fat locks.
+#ifdef SPIN_COUNT
+ for (i = SPIN_COUNT; i >=0; i--, lockword = *lockword_ptr, lock_id = THREAD_ID(lockword)) {
+#endif
+
+ // Check if monitor is free and thin
+ if (lock_id == 0) {
+ // Monitor is free
+ assert( RECURSION(lockword) < 1);
+ assert(this_id > 0 && this_id < 0x8000);
+ // Acquire monitor
+ if (0 != port_atomic_cas16 (((volatile apr_uint16_t*) lockword_ptr)+1,
+ (apr_uint16_t) this_id, 0)) {
+#ifdef SPIN_COUNT
+ continue;
+#else
+ return TM_ERROR_EBUSY;
+#endif
+ }
+
+#ifdef LOCK_RESERVATION
+ //lockword = *lockword_ptr; // this reloading of lockword may be odd, need to investigate;
+ if (IS_RESERVED(lockword)) {
+ TRACE(("initialy reserve lock %x count: %d ", *lockword_ptr, init_reserve_cout++));
+ RECURSION_INC(lockword_ptr, *lockword_ptr);
+ }
+#endif
+ TRACE(("CAS lock %x count: %d ", *lockword_ptr, cas_cout++));
+ return TM_ERROR_NONE;
+ } else
+
+ // Fat monitor
+ if(IS_FAT_LOCK(lockword)) {
+ TRACE(("FAT MONITOR %d \n", ++fat_lock2_count/*, vm_get_object_class_name(lockword_ptr-1)*/));
+ fat_monitor = locktable_get_fat_monitor(FAT_LOCK_ID(lockword)); // find fat_monitor in lock table
+
+ status = hythread_monitor_try_enter(fat_monitor);
+#ifdef SPIN_COUNT
+ if (status == TM_ERROR_EBUSY) {
+ continue;
+ }
+#endif
+ return status;
+ }
+
+#ifdef LOCK_RESERVATION
+ // unreserved busy lock
+ else if (IS_RESERVED(lockword)) {
+ status = unreserve_lock(lockword_ptr);
+ if(status != TM_ERROR_NONE) {
+#ifdef SPIN_COUNT
+ if(status == TM_ERROR_EBUSY) {
+ continue;
+ }
+#endif //SPIN_COUNT
+ return status;
+ }
+ assert(!IS_RESERVED(*lockword_ptr));
+ return hythread_thin_monitor_try_enter(lockword_ptr);
+ }
+#endif
+#ifdef SPIN_COUNT
+ hythread_yield();
+ }
+#endif
+ return TM_ERROR_EBUSY;
+}
+
+
+/**
+ * Locks thin monitor.
+ *
+ * @param[in] lockword_ptr monitor addr
+ */
+IDATA hythread_thin_monitor_enter(hythread_thin_monitor_t *lockword_ptr) {
+ hythread_monitor_t fat_monitor;
+ IDATA status;
+ int saved_disable_count;
+
+ assert(lockword_ptr);
+
+ if (hythread_thin_monitor_try_enter(lockword_ptr) == TM_ERROR_NONE) {
+ return TM_ERROR_NONE;
+ }
+
+ while (hythread_thin_monitor_try_enter(lockword_ptr) == TM_ERROR_EBUSY) {
+ if(IS_FAT_LOCK(*lockword_ptr)) {
+ fat_monitor = locktable_get_fat_monitor(FAT_LOCK_ID(*lockword_ptr)); // find fat_monitor in lock table
+ TRACE((" lock %d\n", FAT_LOCK_ID(*lockword_ptr)));
+ saved_disable_count=reset_suspend_disable();
+ status = hythread_monitor_enter(fat_monitor);
+ set_suspend_disable(saved_disable_count);
+ return status; // lock fat_monitor
+ }
+ //hythread_sefe_point();
+ hythread_yield();
+ }
+ if(IS_FAT_LOCK(*lockword_ptr)) {
+ // lock already inflated
+ return TM_ERROR_NONE;
+ }
+ TRACE(("inflate_contended thin_lcok%d\n", ++inflate_contended));
+ inflate_lock(lockword_ptr);
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Unlocks thin monitor.
+ *
+ * @param[in] lockword_ptr monitor addr
+ */
+IDATA VMCALL hythread_thin_monitor_exit(hythread_thin_monitor_t *lockword_ptr) {
+ IDATA lockword = *lockword_ptr;
+ hythread_monitor_t fat_monitor;
+ IDATA this_id = tm_self_tls->thread_id; // obtain current thread id
+ assert(this_id > 0 && this_id < 0xffff);
+ assert (!hythread_is_suspend_enabled());
+
+ if(THREAD_ID(lockword) == this_id) {
+ if (RECURSION(lockword)==0) {
+#ifdef LOCK_RESERVATION
+ if(IS_RESERVED(lockword)) {
+ TRACE(("ILLEGAL_STATE %x\n", lockword));
+ return TM_ERROR_ILLEGAL_STATE;
+ }
+#endif
+ *lockword_ptr = lockword & 0xffff;
+ } else {
+ RECURSION_DEC(lockword_ptr, lockword);
+ //TRACE(("recursion_dec: 0x%x", *lockword_ptr));
+ }
+ //TRACE(("unlocked: 0x%x id: %d\n", *lockword_ptr, THREAD_ID(*lockword_ptr)));
+ //hythread_sefe_point();
+ return TM_ERROR_NONE;
+ } else if (IS_FAT_LOCK(lockword)) {
+ TRACE(("exit fat monitor %d thread: %d\n", FAT_LOCK_ID(lockword), tm_self_tls->thread_id));
+ fat_monitor = locktable_get_fat_monitor(FAT_LOCK_ID(lockword)); // find fat_monitor
+ return hythread_monitor_exit(fat_monitor); // unlock fat_monitor
+ }
+ TRACE(("ILLEGAL_STATE %d\n", FAT_LOCK_ID(lockword)));
+ return TM_ERROR_ILLEGAL_STATE;
+}
+
+
+IDATA thin_monitor_wait_impl(hythread_thin_monitor_t *lockword_ptr, I_64 ms, IDATA nano, IDATA interruptable) {
+ // get this thread
+ hythread_t this_thread = tm_self_tls;
+ IDATA lockword = *lockword_ptr;
+ hythread_monitor_t fat_monitor;
+
+ if (!IS_FAT_LOCK(lockword)) {
+ // check if the current thread owns lock
+ if (!owns_thin_lock(this_thread, lockword)) {
+ TRACE(("ILLEGAL_STATE %wait d\n", FAT_LOCK_ID(lockword)));
+ return TM_ERROR_ILLEGAL_STATE;
+ }
+ TRACE(("inflate_wait%d\n", ++inflate_waited));
+ // if it is not a thin lock, inflate it
+ fat_monitor = inflate_lock(lockword_ptr);
+ } else {
+ // otherwise, get the appropriate fat lock
+ fat_monitor = locktable_get_fat_monitor(FAT_LOCK_ID(lockword));
+ }
+ assert(fat_monitor == locktable_get_fat_monitor(FAT_LOCK_ID(*lockword_ptr)));
+ return monitor_wait_impl(fat_monitor,ms,nano, interruptable);
+}
+
+/**
+ * Atomically releases a thin monitor and causes the calling
+ * thread to wait on the given condition variable.
+ *
+ * Calling thread must own the monitor. After notification is received, the monitor
+ * is locked again, restoring the original recursion.
+ *
+ * @param[in] lockword_ptr monitor addr
+ * @return
+ * TM_NO_ERROR on success
+ */
+IDATA VMCALL hythread_thin_monitor_wait(hythread_thin_monitor_t *lockword_ptr) {
+ return thin_monitor_wait_impl(lockword_ptr, 0, 0, WAIT_NONINTERRUPTABLE);
+}
+
+/**
+ * Atomically releases a thin monitor and causes the calling
+ * thread to wait for signal.
+ *
+ * Calling thread must own the monitor. After notification is received or time out, the monitor
+ * is locked again, restoring the original recursion.
+ *
+ * @param[in] lockword_ptr monitor addr
+ * @param[in] ms timeout millis
+ * @param[in] nano timeout nanos
+ * @return
+ * TM_NO_ERROR on success
+ * TM_ERROR_TIMEOUT in case of time out.
+ */
+IDATA VMCALL hythread_thin_monitor_wait_timed(hythread_thin_monitor_t *lockword_ptr, I_64 ms, IDATA nano) {
+ return thin_monitor_wait_impl(lockword_ptr, ms, nano, WAIT_NONINTERRUPTABLE);
+}
+
+/**
+ * Atomically releases a thin monitor and causes the calling
+ * thread to wait for signal.
+ *
+ * Calling thread must own the monitor. After notification is received or time out, the monitor
+ * is locked again, restoring the original recursion.
+ *
+ * @param[in] lockword_ptr monitor addr
+ * @param[in] ms timeout millis
+ * @param[in] nano timeout nanos
+ * @return
+ * TM_NO_ERROR on success
+ * TM_THREAD_INTERRUPTED in case thread was interrupted during wait.
+ * TM_ERROR_TIMEOUT in case of time out.
+ */
+IDATA VMCALL hythread_thin_monitor_wait_interruptable(hythread_thin_monitor_t *lockword_ptr, I_64 ms, IDATA nano) {
+ return thin_monitor_wait_impl(lockword_ptr, ms, nano, WAIT_INTERRUPTABLE);
+}
+
+
+/**
+ * Signals a single thread that is blocking on the given monitor to wake up.
+ *
+ * @param[in] lockword_ptr monitor addr
+ */
+IDATA hythread_thin_monitor_notify(hythread_thin_monitor_t *lockword_ptr) {
+ hythread_monitor_t fat_monitor;
+ hythread_thin_monitor_t lockword = *lockword_ptr;
+ if (IS_FAT_LOCK(lockword)) {
+ fat_monitor = locktable_get_fat_monitor(FAT_LOCK_ID(lockword));
+ assert(fat_monitor);
+ return hythread_monitor_notify(fat_monitor);
+ }
+ // check if the current thread owns lock
+ if (!owns_thin_lock(tm_self_tls, lockword)) {
+ return TM_ERROR_ILLEGAL_STATE;
+ }
+
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Signals all threads blocking on the given thin monitor.
+ *
+ * @param[in] lockword_ptr monitor addr
+ */
+IDATA hythread_thin_monitor_notify_all(hythread_thin_monitor_t *lockword_ptr) {
+ hythread_monitor_t fat_monitor;
+ hythread_thin_monitor_t lockword = *lockword_ptr;
+ if (IS_FAT_LOCK(lockword)) {
+ fat_monitor = locktable_get_fat_monitor(FAT_LOCK_ID(lockword));
+ assert(fat_monitor);
+ return hythread_monitor_notify_all(fat_monitor);
+ }
+ // check if the current thread owns lock
+ if (!owns_thin_lock(tm_self_tls, lockword)) {
+ return TM_ERROR_ILLEGAL_STATE;
+ }
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Destroys the thin monitor and releases any associated resources.
+ *
+ * @param[in] lockword_ptr monitor addr
+ */
+IDATA hythread_thin_monitor_destroy(hythread_thin_monitor_t *lockword_ptr) {
+ hythread_monitor_t fat_monitor;
+ hythread_thin_monitor_t lockword = *lockword_ptr;
+
+ if (IS_FAT_LOCK(lockword)) {
+ fat_monitor = locktable_delete_entry(FAT_LOCK_ID(lockword));
+ assert(fat_monitor);
+ return hythread_monitor_destroy(fat_monitor);
+ }
+ return TM_ERROR_NONE;
+}
+
+extern hymutex_t FAT_MONITOR_TABLE_LOCK;
+
+/*
+ * Inflates the compressed lockword into fat fat_monitor
+ */
+hythread_monitor_t VMCALL inflate_lock(hythread_thin_monitor_t *lockword_ptr) {
+ hythread_monitor_t fat_monitor;
+ IDATA status;
+ IDATA fat_monitor_id;
+ IDATA lockword;
+ int i;
+ status=hymutex_lock(FAT_MONITOR_TABLE_LOCK);
+ assert (status == TM_ERROR_NONE);
+ TRACE(("inflate tmj%d\n", ++inflate_count));
+ lockword = *lockword_ptr;
+ if(IS_FAT_LOCK (lockword)) {
+ status=hymutex_unlock(FAT_MONITOR_TABLE_LOCK);
+ assert (status == TM_ERROR_NONE);
+ return locktable_get_fat_monitor(FAT_LOCK_ID(lockword));
+ }
+#ifdef LOCK_RESERVATION
+ // unreserve lock first
+ if (IS_RESERVED(lockword)) {
+ unreserve_self_lock(lockword_ptr);
+ lockword = *lockword_ptr;
+ }
+ assert(!IS_RESERVED(lockword));
+#endif
+
+ assert(owns_thin_lock(tm_self_tls, lockword));
+ assert (!hythread_is_suspend_enabled());
+
+ TRACE (("inflation begin for %x thread: %d", lockword, tm_self_tls->thread_id));
+ status = hythread_monitor_init(&fat_monitor, 0); // allocate fat fat_monitor
+ assert(status == TM_ERROR_NONE);
+ if(status != TM_ERROR_NONE) {
+ hymutex_unlock(FAT_MONITOR_TABLE_LOCK);
+ return NULL;
+ }
+
+ /* removed due to lock acquisition in monitor creation
+ * status = hythread_monitor_enter(fat_monitor); // lock fat fat_monitor
+ * assert(status == TM_ERROR_NONE);
+ */
+ for (i = RECURSION(lockword); i > 0; i--) {
+ TRACE( ("infalte recursion monitor"));
+ status = hythread_monitor_enter(fat_monitor); // transfer recusrion count to fat fat_monitor
+ assert(status == TM_ERROR_NONE);
+ }
+ fat_monitor_id = locktable_put_fat_monitor(fat_monitor); // put fat_monitor into lock table
+ set_fat_lock_id(lockword_ptr, fat_monitor_id);
+ TRACE(("inflate_lock %d thread: %d\n", FAT_LOCK_ID(*lockword_ptr), tm_self_tls->thread_id));
+ //assert(FAT_LOCK_ID(*lockword_ptr) != 2);
+ TRACE(("FAT ID : 0x%x", *lockword_ptr));
+ fat_monitor->inflate_count++;
+ fat_monitor->inflate_owner=tm_self_tls;
+ status=hymutex_unlock(FAT_MONITOR_TABLE_LOCK);
+ assert (status == TM_ERROR_NONE);
+#ifdef LOCK_RESERVATION
+ assert(!IS_RESERVED(*lockword_ptr));
+#endif
+ return fat_monitor;
+}
+
+
+/*
+ * Deflates the fat lock back into compressed lock word.
+ * Not yet implemented.
+ */
+void deflate_lock(hythread_monitor_t fat_monitor, hythread_thin_monitor_t *lockword) {
+/*
+ ;;// put thread_id into lockword
+ //... TODO
+ RECURSION_COUNT(lockword) = fat_monitor->recursion_count; // Transfer recursion count from fat lock back to thin lock
+ IS_FAT_LOCK(lockword) = 0; // Set contention bit indicating that the lock is now thin
+ hythread_monitor_destroy(fat_monitor); // Deallocate fat_monitor
+ locktable_delete_entry(lock_id); // delete entry in lock able
+
+*/
+}
+
+
+
+/*
+ * Lock table which holds the mapping between LockID and fat lock (OS fat_monitor) pointer.
+ */
+
+//FIXME: make table resizable, implement delete
+
+int table_size=8024;
+static hythread_monitor_t lock_table[8024];
+int fat_monitor_count = 1;
+// Lock table implementation
+
+
+
+/*
+ * Returns the OS fat_monitor associated with the given lock id.
+ */
+hythread_monitor_t locktable_get_fat_monitor(IDATA lock_id) {
+ hythread_monitor_t fat_monitor;
+ TRACE(("LOCK ID in table %x\n", lock_id));
+ assert(lock_id >=0 && lock_id < table_size);
+ //hythread_global_lock();
+ fat_monitor = lock_table[lock_id];
+ //hythread_global_unlock();
+ return fat_monitor;
+}
+
+/*
+ * Sets the value of the specific entry in the lock table
+ */
+IDATA locktable_put_fat_monitor(hythread_monitor_t fat_monitor) {
+ int id;
+ //hythread_global_lock();
+ id = fat_monitor_count++;
+ assert(id >=0 && id < table_size);
+ lock_table[id] = fat_monitor;
+ //hythread_global_unlock();
+ return id;
+}
+
+/*
+ * Deletes the entry in the lock table with the given lock_id
+ */
+hythread_monitor_t locktable_delete_entry(int lock_id) {
+ hythread_monitor_t m;
+ assert(lock_id >=0 && lock_id < table_size);
+ m = lock_table[lock_id];
+ lock_table[lock_id] = NULL;
+ return m;
+
+}
+
+/**
+ * Returns the owner of the given thin monitor.
+ *
+ * @param[in] lockword_ptr monitor addr
+ */
+hythread_t VMCALL hythread_thin_monitor_get_owner(hythread_thin_monitor_t *lockword_ptr) {
+ IDATA lockword;
+ hythread_monitor_t fat_monitor;
+
+ assert(lockword_ptr);
+ lockword = *lockword_ptr;
+ if(IS_FAT_LOCK(lockword)) {
+ fat_monitor = locktable_get_fat_monitor(FAT_LOCK_ID(lockword)); // find fat_monitor in lock table
+ return fat_monitor->owner;
+ }
+ return hythread_get_thread(THREAD_ID(lockword));
+}
+
+/**
+ * Returns the recursion count of the given monitor.
+ *
+ * @param[in] lockword_ptr monitor addr
+ */
+IDATA VMCALL hythread_thin_monitor_get_recursion(hythread_thin_monitor_t *lockword_ptr) {
+ IDATA lockword;
+ hythread_monitor_t fat_monitor;
+
+ assert(lockword_ptr);
+ lockword = *lockword_ptr;
+ if(IS_FAT_LOCK(lockword)) {
+ fat_monitor = locktable_get_fat_monitor(FAT_LOCK_ID(lockword)); // find fat_monitor in lock table
+ return fat_monitor->recursion_count;
+ }
+ return RECURSION(lockword);
+}
+
+//@}
Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_thin_monitor.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_tls.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_tls.c?rev=434076&view=auto
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_tls.c (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_tls.c Wed Aug 23 09:48:41 2006
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Nikolay Kuznetsov
+ * @version $Revision: 1.1.2.7 $
+ */
+
+/**
+ * @file thread_native_tls.c
+ * @brief Hythread TLS related functions
+ */
+
+#include <open/hythread_ext.h>
+#include "thread_private.h"
+
+
+/** @name Thread local storage support
+ */
+//@{
+
+int16 tm_tls_capacity = 16;
+int16 tm_tls_size = 0;
+
+static void tls_finalizer_placeholder(void *args) {}
+
+
+/**
+ * Allocate a thread local storage (TLS) key.
+ *
+ * Create and return a new, unique key for thread local storage.
+ *
+ * @note The hande returned will be >=0, so it is safe to test the handle against 0 to see if it's been
+ * allocated yet.
+ *
+ * @param[out] handle pointer to a key to be initialized with a key value
+ * @return 0 on success or negative value if a key could not be allocated (i.e. all TLS has been allocated)
+ *
+ * @see hythread_tls_free, hythread_tls_set
+ */
+IDATA VMCALL hythread_tls_alloc(hythread_tls_key_t *handle) {
+ return hythread_tls_alloc_with_finalizer(handle, tls_finalizer_placeholder);
+}
+
+/**
+ * Allocate a thread local storage (TLS) key.
+ *
+ * Create and return a new, unique key for thread local storage.
+ *
+ * @note The hande returned will be >=0, so it is safe to test the handle against 0 to see if it's been
+ * allocated yet.
+ *
+ * @param[out] handle pointer to a key to be initialized with a key value
+ * @param[in] finalizer a finalizer function which will be invoked when a thread is
+ * detached or terminates if the thread's TLS entry for this key is non-NULL
+ * @return 0 on success or negative value if a key could not be allocated (i.e. all TLS has been allocated)
+ *
+ * @see hythread_tls_free, hythread_tls_set
+ */
+IDATA VMCALL hythread_tls_alloc_with_finalizer(hythread_tls_key_t *handle, hythread_tls_finalizer_t finalizer) {
+ if (tm_tls_size < tm_tls_capacity - 1) {
+ *handle = ++tm_tls_size;
+ return TM_ERROR_NONE;
+ }
+
+ return -1;
+}
+
+/**
+ * Returns a thread's TLS value.
+ */
+void* VMCALL hythread_tls_get(hythread_t thread, hythread_tls_key_t key) {
+ return thread->thread_local_storage[key];
+}
+
+/**
+ * Set a thread's TLS value.
+ *
+ * @param[in] thread a thread
+ * @param[in] key key to have TLS value set (any value returned by hythread_alloc)
+ * @param[in] data value to be stored in TLS
+ * @return 0 on success or negative value on failure
+ *
+ * @see hythread_tls_alloc, hythread_tls_free, hythread_tls_get
+ */
+IDATA VMCALL hythread_tls_set(hythread_t thread, hythread_tls_key_t key, void *data) {
+ assert(thread->thread_local_storage);
+ thread->thread_local_storage[key] = data;
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Release a TLS key.
+ *
+ * Release a TLS key previously allocated by hythread_tls_alloc.
+ *
+ * @param[in] key TLS key to be freed
+ * @return 0 on success or negative value on failure
+ *
+ * @see hythread_tls_alloc, hythread_tls_set
+ */
+IDATA VMCALL hythread_tls_free(hythread_tls_key_t key) {
+ //@TODO: implement entries deletion in TLS
+ return TM_ERROR_NONE;
+}
+
+//@}
Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_tls.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h?rev=434076&view=auto
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h Wed Aug 23 09:48:41 2006
@@ -0,0 +1,634 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Andrey Chernyshev
+ * @version $Revision: 1.1.2.14 $
+ */
+
+
+#ifndef THREAD_PRIVATE_H
+#define THREAD_PRIVATE_H
+
+#include <assert.h>
+//#include <open/thread_types.h>
+#include <stdlib.h>
+#include <open/types.h>
+#include <open/hythread_ext.h>
+#include <open/ti_thread.h>
+#include <open/thread_externals.h>
+#include <apr_pools.h>
+#include <apr_thread_mutex.h>
+#include <apr_thread_cond.h>
+#include <apr_thread_rwlock.h>
+#include <apr_portable.h>
+
+#include <assert.h>
+#include "apr_thread_ext.h"
+
+// temporary remove logging
+#define TRACE(a) //printf a; printf("\n")
+//#include "clog.h"
+
+// FIXME move to the global header, add error converter
+#define RET_ON_ERROR(stat) if(stat) { return -1; }
+#define CONVERT_ERROR(stat) (stat)
+
+#define MAX_OWNED_MONITOR_NUMBER 200 //FIXME: switch to dynamic resize
+#define FAST_LOCAL_STORAGE_SIZE 10
+
+//use lock reservation
+#define LOCK_RESERVATION
+// spin with try_lock SPIN_COUNT times
+#define SPIN_COUNT 5
+
+//use optimized asm monitor enter and exit
+#define ASM_MONITOR_HELPER
+
+// TLS access options
+#ifdef WIN32
+#define FS14_TLS_USE
+#endif
+//#define APR_TLS_USE
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+// optimization code
+#if !defined (APR_TLS_USE ) && !defined (FS14_TLS_USE)
+#ifdef PLATFORM_POSIX
+extern __thread hythread_t tm_self_tls;
+#else
+extern __declspec(thread) hythread_t tm_self_tls;
+#endif
+#else
+
+__forceinline hythread_t tmn_self_macro() {
+ register hythread_t t;
+ _asm { mov eax, fs:[0x14]
+ mov t, eax;
+ }
+ return t;
+}
+
+
+#define store_tm_self(self) (__asm(mov self, fs:[0x14]))
+#define tm_self_tls (tmn_self_macro())
+#endif
+
+
+/**
+ * get_local_pool() function return apr pool asociated with the current thread.
+ * the memory could be allocated without lock using this pool
+ * dealocation 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() synchroniously register the cleanup function.
+ * It shold be called to request cleaunp 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
+
+
+extern hythread_group_t TM_DEFAULT_GROUP;
+/**
+ * current capacity of the thread local storage
+ */
+extern int16 tm_tls_capacity;
+
+/**
+ * current capacity of the thread local storage
+ */
+extern int16 tm_tls_size;
+
+
+typedef struct HyThreadLibrary {
+ IDATA a;
+} HyThreadLibrary;
+
+
+
+/**
+ * Native thread control structure.
+ */
+typedef struct HyThread {
+// Suspension
+
+ /**
+ * Number of suspend requests made for this thread.
+ */
+ IDATA suspend_request;
+
+ /**
+ * Flag indicating that thread can safely be suspended.
+ */
+ int16 suspend_disable_count;
+
+ /**
+ * Event used to notify interested threads whenever thread enters the safe region.
+ */
+ hylatch_t safe_region_event;
+
+ /**
+ * Event used to notify suspended thread that it needs to wake up.
+ */
+ hysem_t resume_event;
+
+ /**
+ * Function to be executed at safepoint upon thread resume.
+ */
+ hythread_event_callback_proc safepoint_callback;
+
+
+// Basic manipulation fields
+
+ /**
+ * Group for this thread. Different groups are needed in order
+ * to be able to quickly iterate over the specific group.
+ * Examples are: Java threads, GC private threads.
+ * Equal to the address of the head of the list of threads for this group.
+ */
+ hythread_group_t group;
+
+ /**
+ * Points to the next thread within the group.
+ */
+ hythread_t next;
+
+ /**
+ * Points to the last thread within the group.
+ */
+
+ hythread_t prev;
+
+ /**
+ * Handle to OS thread.
+ */
+ apr_thread_t *os_handle;
+
+ /**
+ * Placeholder for any data to be associated with this thread.
+ * Java layer is using it to keep java-specific context.
+ */
+ void *private_data;
+
+ /**
+ * Flag indicating there was request to exit
+ */
+ Boolean exit_request;
+
+ /**
+ * Exit value of this thread
+ */
+ IDATA exit_value;
+
+
+// Synchronization stuff
+
+ /**
+ * Event reserved for parking threads.
+ */
+ hysem_t park_event;
+
+ /**
+ * Event reserved for sleeping threads.
+ */
+ hysem_t sleep_event;
+
+ /**
+ * Event reserved for threads that invoke join.
+ */
+ hylatch_t join_event;
+
+ /**
+ * Current conditional variable thread is waiting on (used for interrupting)
+ */
+ hycond_t current_condition;
+
+
+// State
+
+ /**
+ * Thread state. Holds thread state flags as defined in JVMTI specification, plus some additional
+ * flags. See <a href=http://java.sun.com/j2se/1.5.0/docs/guide/jvmti/jvmti.html#GetThreadState>
+ * JVMTI Specification </a> for more details.
+ */
+ IDATA state;
+
+
+// Attributes
+
+ /**
+ * name of the thread (useful for debugging purposes)
+ */
+ char* name;
+
+ /**
+ * Hint for scheduler about thread priority
+ */
+ IDATA priority;
+
+ /**
+ * Is this thread daemon?
+ */
+ IDATA daemon;
+
+
+// Monitors
+
+ /**
+ * ID for this thread. The maximum number of threads is governed by the size of lockword record.
+ */
+ IDATA thread_id;
+
+
+
+ /**
+ * Memory pool in with this thread allocated
+ */
+ apr_pool_t *pool;
+
+ /**
+ * APR thread attributes
+ */
+ apr_threadattr_t *apr_attrs;
+
+
+ /**
+ * Procedure that describes thread body to be executed.
+ */
+ hythread_entrypoint_t start_proc;
+
+ /**
+ * Arguments to be passed to the thread body.
+ */
+ void *start_proc_args;
+
+ /**
+ * Array representing thread local storage
+ */
+ void *thread_local_storage[10];
+
+ /**
+ * Extension to the standard local storage slot.
+ */
+ void **big_local_storage;
+
+} HyThread;
+
+
+/**
+ * Java-specific context that is attached to tm_thread control structure by Java layer
+ */
+typedef struct JVMTIThread {
+
+ /**
+ * JNI env associated with this Java thread
+ */
+ JNIEnv *jenv;
+
+ /**
+ * jthread object which is associated with tm_thread
+ */
+ jthread thread_object;
+
+ /**
+ * Conditional variable which is used to wait/notify on java monitors.
+ */
+ hycond_t monitor_condition;
+
+ /**
+ * Exception that has to be thrown in stopped thread
+ */
+ jthrowable stop_exception;
+
+ /**
+ * Blocked on monitor time in nanoseconds
+ */
+ jlong blocked_time;
+
+ /**
+ * Waited on monitor time in nanoseconds
+ */
+ jlong waited_time;
+
+ /**
+ * JVM TI local storage
+ */
+ JVMTILocalStorage jvmti_local_storage;
+
+ /**
+ * Monitor this thread is blocked on.
+ */
+ jobject contended_monitor;
+
+ /**
+ * Monitor this thread waits on.
+ */
+ jobject wait_monitor;
+
+ /**
+ * Monitors for which this thread is owner.
+ */
+ jobject *owned_monitors;
+
+ /**
+ * owned monitors count.
+ */
+ int owned_monitors_nmb;
+
+ /**
+ * APR pool for this structure
+ */
+ apr_pool_t *pool;
+
+ /**
+ * weak reference to corresponding java.lang.Thread instace
+ */
+ jobject thread_ref;
+
+} JVMTIThread;
+
+
+
+/**
+ * hythread_group_t pointer to the first element in the thread group
+ */
+typedef struct HyThreadGroup {
+
+ /**
+ * Pointer to the first thread in the list of threads
+ * contained in this group
+ */
+ hythread_t thread_list;
+
+
+ /**
+ * Pointer to the first thread in the list of threads
+ * contained in this group
+ */
+ hythread_t thread_list_tail;
+
+ /**
+ * Number of threads in this group
+ */
+ int threads_count;
+
+ /**
+ * Group index or key for search perposes
+ */
+ int group_index;
+
+ /**
+ * Memory pool to place created threads into.
+ */
+ apr_pool_t* pool;
+
+ /**
+ *
+ */
+ hythread_group_t next;
+
+ /**
+ *
+ */
+ hythread_group_t prev;
+
+} HyThreadGroup;
+
+
+/**
+ * Fat monitor structure.
+ *
+ * A simple combination of conditional variable and fat lock.
+ */
+typedef struct HyThreadMonitor {
+
+ /**
+ * Mutex
+ */
+ hymutex_t mutex;
+
+ /**
+ * Condition variable
+ */
+ hycond_t condition;
+
+ /**
+ * Recursion count
+ */
+ IDATA recursion_count;
+ hythread_t owner;
+ hythread_t inflate_owner;
+ hythread_t last_wait;
+ int inflate_count;
+ int wait_count;
+ int notify_flag;
+ /**
+ * monitor sub pool
+ * will be destroyed by monitor_destroy()
+ */
+ apr_pool_t *pool;
+ /**
+ * Owner thread ID.
+ */
+ IDATA thread_id;
+
+ UDATA flags;
+
+ char *name;
+
+} HyThreadMonitor;
+
+/**
+ * Count down latch
+ */
+typedef struct HyLatch {
+
+ /**
+ * Latch count
+ */
+ int count;
+
+ /**
+ * Condition event used to signal threads which are waiting on the latch.
+ */
+ hycond_t condition;
+
+ /**
+ * Mutex associated with the latch data.
+ */
+ hymutex_t mutex;
+ /**
+ * latch sub pool
+ * will be destroyed by latch_destroy()
+ */
+ apr_pool_t *pool;
+
+} HyLatch;
+
+
+/**
+ * Semaphore
+ */
+typedef struct HySemaphore {
+
+ /**
+ * Semaphore count
+ */
+ int count;
+
+ /**
+ * Semaphore max count
+ */
+ int max_count;
+
+ /**
+ * Condition event used to signal threads which are waiting on the semaphore.
+ */
+ hycond_t condition;
+
+ /**
+ * 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
+
+extern hythread_group_t group_list; // list of thread groups
+extern int groups_count; // number of thread groups
+
+extern apr_pool_t *TM_POOL; //global APR pool for thread manager
+
+extern apr_threadkey_t *TM_THREAD_KEY; // Key used to store tm_thread_t structure in TLS
+
+extern int max_group_index; // max number of groups
+
+
+#define THREAD_ID_SIZE 16 //size of thread ID in bits. Also defines max number of threads
+
+
+
+/**
+* Internal TM functions
+*/
+
+/**
+* tm_reset_suspend_disable() reset <code>suspend_disable</code> to 0, and return old value.
+* It should be used with tm_set_suspend_disable() to implement safe points
+* Will be used in tm_safe_point(), tm_mutex_lock(), tm_cond_wait().
+*/
+
+int reset_suspend_disable();
+void set_suspend_disable(int count);
+
+/* thin monitor functions used java monitor
+ */
+IDATA is_fat_lock(hythread_thin_monitor_t lockword);
+IDATA owns_thin_lock(hythread_t thread, IDATA lockword);
+hythread_monitor_t inflate_lock(hythread_thin_monitor_t *lockword_ptr);
+IDATA unreserve_lock(IDATA *lockword_ptr);
+
+
+/**
+ * Auxiliary function to throw java.lang.InterruptedException
+ */
+
+void throw_interrupted_exception(void);
+
+hythread_group_t get_java_thread_group(void);
+
+/**
+ * Thread cancelation, being used at VM shutdown through
+ * tmj_cancel_all_threads() method call to terminate all java
+ * threads at shutdown.
+ */
+
+IDATA countdown_nondaemon_threads();
+IDATA increase_nondaemon_threads_count();
+
+IDATA VMCALL hythread_create_with_group(hythread_t *ret_thread, hythread_group_t group, UDATA stacksize, UDATA priority, UDATA suspend, hythread_entrypoint_t func, void *data);
+
+typedef void (*tm_thread_event_callback_proc)(void);
+IDATA VMCALL set_safepoint_callback(hythread_t thread, tm_thread_event_callback_proc callback);
+
+IDATA acquire_start_lock(void);
+IDATA release_start_lock(void);
+
+IDATA thread_destroy(hythread_t thread);
+IDATA VMCALL hythread_get_group(hythread_group_t *group, hythread_t thread);
+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 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);
+
+typedef struct ResizableArrayEntry {
+ void *entry;
+ UDATA next_free;
+} ResizableArrayEntry;
+
+typedef struct ResizableArrayEntry *array_entry_t;
+
+typedef struct ResizableArrayType {
+ UDATA size;
+ UDATA capacity;
+ UDATA next_index;
+ array_entry_t entries;
+} ResizableArrayType;
+typedef struct ResizableArrayType *array_t;
+
+
+IDATA array_create(array_t *array);
+IDATA array_destroy(array_t array);
+UDATA array_add(array_t array, void *value);
+void *array_delete(array_t array, UDATA index);
+void *array_get(array_t array, UDATA index);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* THREAD_PRIVATE_H */
Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_instr.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_instr.c?rev=434076&view=auto
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_instr.c (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_instr.c Wed Aug 23 09:48:41 2006
@@ -0,0 +1,525 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Sergey Petrovsky
+ * @version $Revision: 1.1.2.10 $
+ */
+
+/**
+ * @file thread_ti_instr.c
+ * @brief JVMTI basic related functions
+ */
+
+#include <open/ti_thread.h>
+#include <open/hythread_ext.h>
+#include <open/jthread.h>
+#include "thread_private.h"
+
+/**
+ * Returns the list of all Java threads.
+ *
+ * @param[out] threads resulting threads list
+ * @param[out] count_ptr number of threads in the resulting list
+ */
+IDATA VMCALL jthread_get_all_threads(jthread** threads, jint *count_ptr) {
+
+ hythread_group_t java_thread_group = get_java_thread_group();
+ hythread_iterator_t iterator;
+ hythread_t tm_native_thread;
+ jvmti_thread_t tm_java_thread;
+ jthread* java_threads;
+ int i;
+ int count = 0;
+ int java_thread_count = 0;
+ IDATA status;
+ //apr_status_t apr_status;
+ //apr_pool_t *pool;
+
+ assert(java_thread_group);
+ iterator = hythread_iterator_create(java_thread_group);
+ count = hythread_iterator_size (iterator);
+ for (i = 0; i < count; i++){
+ tm_native_thread = hythread_iterator_next(&iterator);
+ tm_java_thread = hythread_get_private_data(tm_native_thread);
+ if (tm_java_thread){
+ java_thread_count++;
+ }
+ }
+ /*apr_status = apr_pool_create(&pool, 0);
+ if (apr_status != APR_SUCCESS){
+ hythread_iterator_release(&iterator);
+ return CONVERT_ERROR(apr_status);
+ }
+ java_threads = apr_palloc(pool, sizeof(jthread)* java_thread_count);*/
+ java_threads = (jthread*)malloc(sizeof(jthread)* java_thread_count);
+ if (!java_threads){
+ hythread_iterator_release(&iterator);
+ return TM_ERROR_OUT_OF_MEMORY;
+ }
+ hythread_iterator_reset(&iterator);
+ java_thread_count = 0;
+ for (i = 0; i < count; i++){
+ tm_native_thread = hythread_iterator_next(&iterator);
+ tm_java_thread = hythread_get_private_data(tm_native_thread);
+ if (tm_java_thread){
+ java_threads[java_thread_count] = tm_java_thread->thread_object;
+ java_thread_count++;
+ }
+ }
+ *threads = java_threads;
+ *count_ptr = java_thread_count;
+ status = hythread_iterator_release(&iterator);
+
+ return status;
+}
+/*
+ */
+IDATA deads_expand(jthread **deads, int deads_size){
+
+ jthread *new_deads;
+ int i;
+ new_deads = (jthread *)malloc(sizeof(jthread) * deads_size * 2);
+ if (!new_deads) return TM_ERROR_OUT_OF_MEMORY;
+
+ for (i = 0; i < deads_size; i++){
+ new_deads[i] = (*deads)[i];
+ }
+ *deads = new_deads;
+ return TM_ERROR_NONE;
+}
+/*
+ */
+int deads_find(jobject thread, jobject *deads, int base, int top, int deads_size){
+
+ int i;
+
+ for (i = 0; i < top; i++){
+ if (vm_objects_are_equal(thread, deads[i])){
+ return 1;
+ }
+ }
+ return 0;
+}
+// FIXME: synchronization and maybe thread suspension needed
+/**
+ * Checks for the deadlock conditions within the specified thread list.
+ *
+ * @param[in] thread_list thread list where to search for deadlock conditions
+ * @param[in] thread_count number of threads in the thread list
+ * @param[out] dead_list deadlocked threads
+ * @param[out] dead_count number of deadlocked threads
+ */
+IDATA VMCALL jthread_get_deadlocked_threads(jthread *thread_list, jint thread_count, jthread **dead_list, jint *dead_count) {
+
+ jthread *deads;
+ int deads_size = 1;
+ int deads_base = 0;
+ int deads_top = 0;
+ jthread *output;
+ int output_top = 0;
+ jobject monitor;
+ jthread thread;
+ //apr_pool_t *pool;
+ /*apr_pool_t *pool_out;
+ apr_status_t apr_status;*/
+ IDATA status;
+ int i;
+
+ /*apr_status = apr_pool_create(&pool, NULL);
+ if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status);
+
+ deads = apr_palloc(pool, sizeof(jthread) * deads_size);
+ output = apr_palloc(pool, sizeof(jthread) * thread_count);
+ if (!deads || !output) return TM_ERROR_OUT_OF_MEMORY;*/
+
+ deads = (jthread *)malloc(sizeof(jthread) * deads_size);
+ output = (jthread *)malloc(sizeof(jthread) * thread_count);
+ if ((deads==NULL)||(output==NULL))
+ {
+ return TM_ERROR_OUT_OF_MEMORY;
+ }
+ for (i = 0; i < thread_count; i++){
+ thread = thread_list[i];
+ while (1){
+ status=jthread_get_contended_monitor(thread, &monitor);
+ if (status != TM_ERROR_NONE) return status;
+ if (! monitor){
+ deads_top = deads_base; // remove frame
+ break;
+ }
+ if (deads_find(thread, deads, deads_base, deads_top, deads_size)){
+ output[output_top] = thread;
+ output_top++;
+ deads_base = deads_top; // add frame
+ break;
+ }
+ if (deads_top == deads_size){
+ status = deads_expand(&deads, deads_size);
+ if (status != TM_ERROR_NONE) return status;
+ }
+ deads[deads_top] = thread;
+ deads_top++;
+ status = jthread_get_lock_owner(monitor, &thread);
+ if (status != TM_ERROR_NONE) return status;
+ }
+ }
+ if (output_top > 0){
+ /* apr_status = apr_pool_create(&pool_out, NULL);
+ if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status);*/
+ *dead_list = (jthread *)malloc(sizeof(jthread) * output_top);
+ if (! *dead_list) return TM_ERROR_OUT_OF_MEMORY;
+
+ for (i = 0; i < output_top; i++){
+ (*dead_list)[i] = output[i];
+ }
+ } else {
+ *dead_list = NULL;
+ }
+ *dead_count = output_top;
+
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Returns the number of all Java threads.
+ *
+ * @param[out] count_ptr number of threads.
+ */
+IDATA VMCALL jthread_get_thread_count(jint *count_ptr) {
+
+ hythread_group_t java_thread_group = get_java_thread_group();
+ hythread_iterator_t iterator;
+ hythread_t tm_native_thread;
+ jvmti_thread_t tm_java_thread;
+ int i;
+ int count = 0;
+ int java_thread_count = 0;
+ IDATA status;
+
+ assert(java_thread_group);
+ iterator = hythread_iterator_create(java_thread_group);
+ count = hythread_iterator_size (iterator);
+ for (i = 0; i < count; i++){
+ tm_native_thread = hythread_iterator_next(&iterator);
+ tm_java_thread = hythread_get_private_data(tm_native_thread);
+ if (tm_java_thread){
+ java_thread_count++;
+ }
+ }
+ *count_ptr = java_thread_count;
+ status = hythread_iterator_release(&iterator);
+
+ return status;
+}
+
+/**
+ * Returns the number of blocked threads.
+ *
+ * @param[out] count_ptr number of threads.
+ */
+IDATA VMCALL jthread_get_blocked_count(jint* count_ptr) {
+
+ hythread_group_t java_thread_group = get_java_thread_group();
+ hythread_iterator_t iterator;
+ hythread_t tm_native_thread;
+ int nmb = 0;
+ int count;
+ IDATA status;
+
+ assert(java_thread_group);
+ iterator = hythread_iterator_create(java_thread_group);
+ count = hythread_iterator_size (iterator);
+
+ while(hythread_iterator_has_next(iterator)){
+ tm_native_thread = hythread_iterator_next(&iterator);
+ if (tm_native_thread && hythread_is_blocked_on_monitor_enter(tm_native_thread)){
+ nmb++;
+ }
+ }
+ *count_ptr = nmb;
+ status = hythread_iterator_release(&iterator);
+
+ return status;
+}
+
+/**
+ * Returns the number of waiting threads.
+ *
+ * @param[out] count number of threads.
+ */
+IDATA VMCALL jthread_get_waited_count(jint* count) {
+
+ hythread_group_t java_thread_group = get_java_thread_group();
+ hythread_iterator_t iterator;
+ hythread_t tm_native_thread;
+ int nmb = 0;
+ IDATA status;
+
+ assert(java_thread_group);
+ iterator = hythread_iterator_create(java_thread_group);
+
+ while(hythread_iterator_has_next(iterator)){
+ tm_native_thread = hythread_iterator_next(&iterator);
+ //if (hythread_is_in_monitor_wait(tm_native_thread)){ ???????????????????????
+ if (hythread_is_waiting(tm_native_thread)){
+ nmb++;
+ }
+ }
+ *count = nmb;
+ status = hythread_iterator_release(&iterator);
+
+ return status;
+}
+
+/**
+ * Returns the <code>thread</code>'s state according
+ * to JVMTI specification. See <a href=http://java.sun.com/j2se/1.5.0/docs/guide/jvmti/jvmti.html#GetThreadState>
+ * JVMTI Specification </a> for more details.
+ *
+ * @param[in] java_thread thread those state is to be queried
+ * @param[out] state resulting thread state
+ *
+ */
+IDATA VMCALL jthread_get_state(jthread java_thread, jint *state) {
+
+ hythread_t tm_native_thread;
+
+ assert(java_thread);
+ assert(state);
+ tm_native_thread = vm_jthread_get_tm_data(java_thread);
+
+ *state = 0;
+
+ if (! tm_native_thread) return TM_ERROR_NONE; // Not started yet
+
+ if (hythread_is_alive(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_ALIVE;}
+ if (hythread_is_runnable(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_RUNNABLE;}
+ if (hythread_is_blocked_on_monitor_enter(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;}
+ if (hythread_is_waiting(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_WAITING;}
+ if (hythread_is_waiting_indefinitely(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY;}
+ if (hythread_is_waiting_with_timeout(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;}
+ if (hythread_is_sleeping(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_SLEEPING;}
+ if (hythread_is_in_monitor_wait(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;}
+ if (hythread_is_parked(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_PARKED;}
+ if (hythread_is_suspended(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_SUSPENDED;}
+ if (hythread_interrupted(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_INTERRUPTED;}
+ if (hythread_is_in_native(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_IN_NATIVE;}
+
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Puts the data into thread local storage.
+ *
+ * @param[in] java_thread thread where to put the data
+ * @param[in] data data to be put
+ */
+IDATA VMCALL jthread_set_local_storage(jthread java_thread, const void* data) {
+
+ hythread_t tm_native_thread;
+
+ assert(java_thread);
+ tm_native_thread = vm_jthread_get_tm_data(java_thread);
+ assert(tm_native_thread);
+
+ return hythread_set_private_data(tm_native_thread, (void *)data);
+}
+
+/**
+ * Extracts the data from the thread local storage.
+ *
+ * @param[in] java_thread thread where to get the data
+ * @param[out] data_ptr pointer to the data
+ */
+IDATA VMCALL jthread_get_local_storage(jthread java_thread, void** data_ptr) {
+
+ hythread_t tm_native_thread;
+
+ assert(java_thread);
+ assert(data_ptr);
+ tm_native_thread = vm_jthread_get_tm_data(java_thread);
+ assert(tm_native_thread);
+ *data_ptr = hythread_get_private_data (tm_native_thread);
+
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Returns true if specified thread holds the lock associated with the given monitor.
+ *
+ * @param[in] thread thread which may hold the lock
+ * @param[in] monitor object those monitor is possibly locked
+ * @return true if thread holds the lock, false otherwise;
+ */
+jboolean VMCALL jthread_holds_lock(jthread thread, jobject monitor) {
+
+ jthread lock_owner;
+ IDATA status;
+ jboolean res;
+
+ status = jthread_get_lock_owner(monitor, &lock_owner);
+ assert(status == TM_ERROR_NONE);
+
+ hythread_suspend_disable();
+ res = vm_objects_are_equal(thread, lock_owner);
+ hythread_suspend_enable();
+
+ return res;
+}
+
+/**
+ * Returns the monitor the specific thread is currently contending for.
+ *
+ * @param[in] java_thread thread to be explored for contention
+ * @param[out] monitor monitor the thread <code>thread</code> is currently contending for,
+ * or NULL if thread doesn't contend for any monitor.
+ */
+IDATA VMCALL jthread_get_contended_monitor(jthread java_thread, jobject* monitor) {
+
+ hythread_t tm_native_thread;
+ jvmti_thread_t tm_java_thread;
+
+ assert(java_thread);
+ tm_native_thread = vm_jthread_get_tm_data(java_thread);
+ tm_java_thread = hythread_get_private_data(tm_native_thread);
+ assert(tm_java_thread);
+ *monitor = tm_java_thread->contended_monitor;
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Returns the monitor the specific thread is currently waiting on.
+ *
+ * @param[in] java_thread thread to be explored for contention
+ * @param[out] monitor monitor the thread <code>thread</code> is currently contending for,
+ * or NULL if thread doesn't contend for any monitor.
+ */
+IDATA VMCALL jthread_get_wait_monitor(jthread java_thread, jobject* monitor) {
+
+ hythread_t tm_native_thread;
+ jvmti_thread_t tm_java_thread;
+
+ assert(java_thread);
+ tm_native_thread = vm_jthread_get_tm_data(java_thread);
+ tm_java_thread = hythread_get_private_data(tm_native_thread);
+ assert(tm_java_thread);
+ *monitor = tm_java_thread->wait_monitor;
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Returns the owner of the lock associated with the given monitor.
+ *
+ * If the given monitor is not owned by any thread, NULL is returned.
+ *
+ * @param[in] monitor monitor those owner needs to be determined
+ * @param[out] lock_owner thread which owns the monitor
+ */
+IDATA VMCALL jthread_get_lock_owner(jobject monitor, jthread* lock_owner) {
+
+ hythread_t tm_native_thread = NULL;
+ jvmti_thread_t tm_java_thread = NULL;
+ hythread_thin_monitor_t *lockword;
+
+ assert(monitor);
+ hythread_suspend_disable();
+ lockword = vm_object_get_lockword_addr(monitor);
+ tm_native_thread = hythread_thin_monitor_get_owner(lockword);
+ if (!tm_native_thread){
+ *lock_owner = NULL;
+ } else {
+ tm_java_thread = hythread_get_private_data(tm_native_thread);
+ *lock_owner = tm_java_thread->thread_object;
+ }
+ hythread_suspend_enable();
+
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Returns the number of times given thread have entered given monitor;
+ *
+ * If the given monitor is not owned by this thread, 0 is returned.
+ *
+ * @param[in] monitor monitor those owner needs to be determined
+ * @param[in] owner thread which owns the monitor
+ */
+IDATA VMCALL jthread_get_lock_recursion(jobject monitor, jthread owner) {
+
+ hythread_t given_thread, lock_owner = NULL;
+ jvmti_thread_t tm_java_thread = NULL;
+ hythread_thin_monitor_t *lockword;
+ IDATA recursion = 0;
+
+ assert(monitor);
+ hythread_suspend_disable();
+ given_thread = owner?vm_jthread_get_tm_data(owner):NULL;
+
+ lockword = vm_object_get_lockword_addr(monitor);
+ lock_owner = hythread_thin_monitor_get_owner(lockword);
+
+ if (lock_owner && (!given_thread || lock_owner->thread_id == given_thread->thread_id))
+ recursion = hythread_thin_monitor_get_recursion(lockword);
+
+ hythread_suspend_enable();
+
+ return recursion;
+}
+
+/**
+ * Returns all monitors owned by the specific thread.
+ *
+ * @param[in] java_thread thread which owns monitors
+ * @param[out] monitor_count_ptr number of owned monitors
+ * @param[out] monitors_ptr array of owned monitors
+ */
+IDATA VMCALL jthread_get_owned_monitors(jthread java_thread,
+ jint* monitor_count_ptr, jobject** monitors_ptr) {
+
+ hythread_t tm_native_thread;
+ jvmti_thread_t tm_java_thread;
+ apr_pool_t* pool;
+ apr_status_t apr_status;
+ jobject* monitors;
+ int i;
+ IDATA status;
+
+ status =hythread_global_lock();
+ if (status != TM_ERROR_NONE) return status;
+ assert(java_thread);
+ tm_native_thread = vm_jthread_get_tm_data(java_thread);
+ tm_java_thread = hythread_get_private_data(tm_native_thread);
+ assert(tm_java_thread);
+ apr_status = apr_pool_create(&pool, 0);
+ if (apr_status != APR_SUCCESS) {
+ hythread_global_unlock();
+ return TM_ERROR_INTERNAL;
+ }
+ monitors = apr_palloc(pool, sizeof(jobject*) * tm_java_thread->owned_monitors_nmb);
+ if (!monitors) {
+ hythread_global_unlock();
+ return TM_ERROR_OUT_OF_MEMORY;
+ }
+ for (i = 0; i < tm_java_thread->owned_monitors_nmb; i++){
+ monitors[i] = tm_java_thread->owned_monitors[i];
+ }
+ *monitors_ptr = monitors;
+ *monitor_count_ptr = tm_java_thread->owned_monitors_nmb;
+
+ status = hythread_global_unlock();
+ return status;
+}
Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_instr.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_monitors.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_monitors.c?rev=434076&view=auto
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_monitors.c (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_monitors.c Wed Aug 23 09:48:41 2006
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Artem Aliev
+ * @version $Revision: 1.1.2.7 $
+ */
+
+/**
+ * @file thread_ti_monitors.c
+ * @brief JVMTI raw monitors related functions
+ */
+
+#include <open/hythread_ext.h>
+#include "thread_private.h"
+
+static array_t jvmti_monitor_table = 0;
+static hymutex_t jvmti_monitor_table_lock;
+
+//#define jrawMonitorID hythread_monitor_t;
+/**
+ * Initializes raw monitor.
+ *
+ * Raw monitors are a simple combination of mutex and conditional variable which is
+ * not associated with any Java object. This function creates the raw monitor at the
+ * address specified as mon_ptr.
+ * User needs to allocate space equal to sizeof(jrawMonitorID) before doing this call.
+ *
+ * @param[in] mon_ptr address where monitor needs to be created and initialized.
+ */
+IDATA VMCALL jthread_raw_monitor_create(jrawMonitorID* mon_ptr) {
+ hythread_monitor_t monitor;
+ IDATA status;
+ status = hythread_monitor_init(&monitor, 0);
+ if (status != TM_ERROR_NONE) return status;
+ //hythread monitor init also locks it
+ status = hythread_monitor_exit(monitor);
+ if (status != TM_ERROR_NONE) return status;
+ // possibly should be moved to jvmti(environment?) init section
+ ////
+ if (!jvmti_monitor_table) {
+ status =hythread_global_lock();
+ if (status != TM_ERROR_NONE) return status;
+ if (!jvmti_monitor_table) {
+
+ if (array_create(&jvmti_monitor_table)) {
+ hythread_global_unlock();
+ return TM_ERROR_OUT_OF_MEMORY;
+ }
+ status =hymutex_create(&jvmti_monitor_table_lock, TM_MUTEX_NESTED);
+ if (status != TM_ERROR_NONE){
+ hythread_global_unlock();
+ return status;
+ }
+ }
+ status =hythread_global_unlock();
+ if (status != TM_ERROR_NONE) return status;
+ }
+
+ 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);
+ if (status != TM_ERROR_NONE) return status;
+ if (!(*mon_ptr)) return TM_ERROR_OUT_OF_MEMORY;
+
+ return TM_ERROR_NONE;
+
+}
+
+/**
+ * Destroys raw monitor.
+ *
+ * @param[in] mon_ptr address where monitor needs to be destroyed.
+ */
+IDATA VMCALL jthread_raw_monitor_destroy(jrawMonitorID mon_ptr) {
+ IDATA status = 0;
+ hythread_monitor_t monitor;
+
+ if (!(monitor = (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr))) {
+ return TM_ERROR_INVALID_MONITOR;
+ }
+
+ while(hythread_monitor_destroy((hythread_monitor_t)monitor) != TM_ERROR_NONE) {
+ if ((status = hythread_monitor_exit((hythread_monitor_t)monitor)) != TM_ERROR_NONE)
+ return status;
+ }
+
+ 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);
+ return status;
+}
+
+/**
+ * Gains the ownership over monitor.
+ *
+ * Current thread blocks if the specified monitor is owned by other thread.
+ *
+ * @param[in] mon_ptr monitor
+ */
+IDATA VMCALL jthread_raw_monitor_enter(jrawMonitorID mon_ptr) {
+ hythread_monitor_t monitor;
+ if (!(monitor = (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr))) {
+ return TM_ERROR_INVALID_MONITOR;
+ }
+ return hythread_monitor_enter(monitor);
+}
+
+/**
+ * Attempt to gain the ownership over monitor without blocking.
+ *
+ * @param[in] mon_ptr monitor
+ * @return 0 in case of successful attempt.
+ */
+IDATA VMCALL jthread_raw_monitor_try_enter(jrawMonitorID mon_ptr) {
+ hythread_monitor_t monitor;
+ if (!(monitor = (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr))) {
+ return TM_ERROR_INVALID_MONITOR;
+ }
+ return hythread_monitor_try_enter((hythread_monitor_t)monitor);
+}
+
+/**
+ * Releases the ownership over monitor.
+ *
+ * @param[in] mon_ptr monitor
+ */
+IDATA VMCALL jthread_raw_monitor_exit(jrawMonitorID mon_ptr) {
+ hythread_monitor_t monitor;
+ if (!(monitor = (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr))) {
+ return TM_ERROR_INVALID_MONITOR;
+ }
+ return hythread_monitor_exit(monitor);
+}
+
+/**
+ * Wait on the monitor.
+ *
+ * This function instructs the current thread to be scheduled off
+ * the processor and wait on the monitor until the following occurs:
+ * <UL>
+ * <LI>another thread invokes <code>thread_notify(object)</code>
+ * and VM chooses this thread to wake up;
+ * <LI>another thread invokes <code>thread_notifyAll(object);</code>
+ * <LI>another thread invokes <code>thread_interrupt(thread);</code>
+ * <LI>real time elapsed from the waiting begin is
+ * greater or equal the timeout specified.
+ * </UL>
+ *
+ * @param[in] mon_ptr monitor
+ * @param[in] millis timeout in milliseconds. Zero timeout is not taken into consideration.
+ * @return
+ * TM_ERROR_NONE success
+ * TM_ERROR_INTERRUPT wait was interrupted
+ * TM_ERROR_INVALID_MONITOR current thread isn't the owner
+ */
+IDATA VMCALL jthread_raw_monitor_wait(jrawMonitorID mon_ptr, int64 millis) {
+ hythread_monitor_t monitor;
+ if (!(monitor = (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr))) {
+ return TM_ERROR_INVALID_MONITOR;
+ }
+ return hythread_monitor_wait_interruptable(monitor, millis, 0);
+}
+
+/**
+ * Notifies one thread waiting on the monitor.
+ *
+ * Only single thread waiting on the
+ * object's monitor is waked up.
+ * Nothing happens if no threads are waiting on the monitor.
+ *
+ * @param[in] mon_ptr monitor
+ */
+IDATA VMCALL jthread_raw_monitor_notify(jrawMonitorID mon_ptr) {
+ hythread_monitor_t monitor;
+ if (!(monitor = (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr))) {
+ return TM_ERROR_INVALID_MONITOR;
+ }
+ return hythread_monitor_notify(monitor);
+}
+
+/**
+ * Notifies all threads which are waiting on the monitor.
+ *
+ * Each thread from the set of threads waiting on the
+ * object's monitor is waked up.
+ *
+ * @param[in] mon_ptr monitor
+ */
+IDATA VMCALL jthread_raw_monitor_notify_all(jrawMonitorID mon_ptr) {
+ hythread_monitor_t monitor;
+ if (!(monitor = (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr))) {
+ return TM_ERROR_INVALID_MONITOR;
+ }
+ return hythread_monitor_notify_all(monitor);
+}
Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_monitors.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_others.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_others.c?rev=434076&view=auto
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_others.c (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_others.c Wed Aug 23 09:48:41 2006
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Sergey Petrovsky
+ * @version $Revision: 1.1.2.4 $
+ */
+
+/**
+ * @file thread_ti_others.c
+ * @brief JVMTI peak related functions
+ */
+
+#include <open/jthread.h>
+#include <open/hythread_ext.h>
+#include <open/ti_thread.h>
+#include "thread_private.h"
+
+/*
+ * Peak count
+ */
+
+/**
+ * Resets the thread peak counter.
+ */
+IDATA jthread_reset_peak_thread_count () {
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Returns the peak thread count since the last peak reset.
+ */
+IDATA jthread_get_peak_thread_count (jint *threads_count_ptr) {
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Returns JVMTILocalStorage pointer.
+ *
+ * @param[in] java_thread
+ */
+JVMTILocalStorage* jthread_get_jvmti_local_storage(jthread java_thread){
+
+ jvmti_thread_t tm_java_thread;
+ hythread_t tm_native_thread;
+
+ tm_native_thread = vm_jthread_get_tm_data(java_thread);
+ tm_java_thread = hythread_get_private_data(tm_native_thread);
+
+ return &tm_java_thread->jvmti_local_storage;
+
+}
Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_others.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_timing.c
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_timing.c?rev=434076&view=auto
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_timing.c (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_timing.c Wed Aug 23 09:48:41 2006
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Sergey Petrovsky
+ * @version $Revision: 1.1.2.7 $
+ */
+
+/**
+ * @file thread_ti_timing.c
+ * @brief JVMTI timing related functions
+ */
+
+#include <open/ti_thread.h>
+#include <open/hythread_ext.h>
+#include <open/jthread.h>
+#include "thread_private.h"
+#include "apr_thread_ext.h"
+
+/**
+ * Returns time spent by the specific thread while contending for monitors.
+ *
+ * @param[in] java_thread
+ * @param[out] nanos_ptr CPU time in nanoseconds
+ */
+IDATA VMCALL jthread_get_thread_blocked_time(jthread java_thread, jlong *nanos_ptr) {
+
+ jvmti_thread_t tm_java_thread;
+ hythread_t tm_native_thread;
+
+ assert(java_thread);
+ assert(nanos_ptr);
+ tm_native_thread = vm_jthread_get_tm_data(java_thread);
+ tm_java_thread = hythread_get_private_data(tm_native_thread);
+ *nanos_ptr = tm_java_thread->blocked_time;
+
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Returns time utilized by given thread.
+ *
+ * @param[in] java_thread
+ * @param[out] nanos_ptr CPU time in nanoseconds
+ */
+IDATA VMCALL jthread_get_thread_cpu_time(jthread java_thread, jlong *nanos_ptr) {
+
+ hythread_t tm_native_thread;
+ apr_time_t kernel_time;
+ apr_time_t 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);
+ *nanos_ptr = kernel_time + user_time;
+
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Returns information about the system timer.
+ *
+ * @param[out] info_ptr timer info
+ */
+IDATA VMCALL jthread_get_thread_cpu_timer_info(jvmtiTimerInfo* info_ptr) {
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Returns time utilized by the given thread in user mode.
+ *
+ * @param[in] java_thread
+ * @param[out] nanos_ptr CPU time in nanoseconds
+ */
+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;
+
+ 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);
+ *nanos_ptr = user_time;
+
+ return TM_ERROR_NONE;
+}
+
+/**
+ * Returns time spent by the specific thread while waiting for monitors.
+ *
+ * @param[in] java_thread
+ * @param[out] nanos_ptr CPU time in nanoseconds
+ */
+IDATA VMCALL jthread_get_thread_waited_time(jthread java_thread, jlong *nanos_ptr) {
+
+ jvmti_thread_t tm_java_thread;
+ hythread_t tm_native_thread;
+
+ assert(java_thread);
+ assert(nanos_ptr);
+ tm_native_thread = vm_jthread_get_tm_data(java_thread);
+ tm_java_thread = hythread_get_private_data(tm_native_thread);
+ *nanos_ptr = tm_java_thread->waited_time;
+
+ return TM_ERROR_NONE;
+}
Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_timing.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/classloader.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/classloader.h?rev=434076&r1=434075&r2=434076&view=diff
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/classloader.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/classloader.h Wed Aug 23 09:48:41 2006
@@ -82,7 +82,7 @@
WaitingThread* m_waitingThreads;
// this event is signaled when class loader finishes
// (successfully or unsuccessfully) loading this class
- VmEventHandle m_loadWaitEvent;
+ int m_loadWaitFlag;
// thread which owns class definition
VM_thread* m_defineOwner;
// thread which first started loading this class
@@ -94,7 +94,7 @@
#endif
m_threadsPool(NULL),
m_waitingThreads(NULL),
- m_loadWaitEvent(0),
+ m_loadWaitFlag(0),
m_defineOwner(NULL),
m_initiatingThread(NULL) {}
LoadingClass(const LoadingClass& lc) {
@@ -103,7 +103,7 @@
#endif
m_threadsPool = lc.m_threadsPool;
m_waitingThreads = lc.m_waitingThreads;
- m_loadWaitEvent = lc.m_loadWaitEvent;
+ m_loadWaitFlag = lc.m_loadWaitFlag;
m_defineOwner = lc.m_defineOwner;
m_initiatingThread = lc.m_initiatingThread;
}
@@ -113,7 +113,7 @@
#endif
m_threadsPool = lc.m_threadsPool;
m_waitingThreads = lc.m_waitingThreads;
- m_loadWaitEvent = lc.m_loadWaitEvent;
+ m_loadWaitFlag = lc.m_loadWaitFlag;
m_defineOwner = lc.m_defineOwner;
m_initiatingThread = lc.m_initiatingThread;
@@ -124,20 +124,16 @@
apr_pool_destroy(m_threadsPool);
m_threadsPool = NULL;
}
- if(m_loadWaitEvent != 0) {
- vm_destroy_event(m_loadWaitEvent);
- m_loadWaitEvent = 0;
- }
+ m_loadWaitFlag = 0;
}
- bool CreateWaitingEvent(const String* className);
void WaitLoading() {
- assert(m_loadWaitEvent != 0);
- vm_wait_for_single_object(m_loadWaitEvent, INFINITE);
+ while(!m_loadWaitFlag) {
+ hythread_yield();
+ }
}
void SignalLoading() {
- if(m_loadWaitEvent != 0)
- vm_set_event(m_loadWaitEvent);
+ m_loadWaitFlag = 1;
}
bool IsDefiner(VM_thread* thread) { return m_defineOwner == thread; }
bool HasDefiner() { return m_defineOwner != NULL; }
@@ -153,6 +149,7 @@
// this operation should be synchronized
void RemoveWaitingThread(VM_thread* thread, ClassLoader* cl, const String* clsname);
bool HasWaitingThreads() { return (m_waitingThreads != NULL); }
+
};
public:
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/dll_jit_intf.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/dll_jit_intf.h?rev=434076&r1=434075&r2=434076&view=diff
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/dll_jit_intf.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/dll_jit_intf.h Wed Aug 23 09:48:41 2006
@@ -27,7 +27,6 @@
#include "jit_export_jpda.h"
#include <apr_dso.h>
#include <apr_dso.h>
-#include "open/thread.h"
bool vm_is_a_jit_dll(const char *dll_filename);
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/exceptions.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/exceptions.h?rev=434076&r1=434075&r2=434076&view=diff
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/exceptions.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/exceptions.h Wed Aug 23 09:48:41 2006
@@ -243,6 +243,8 @@
// rth_throw_incompatible_class_change_exception throws an incompatible class change exception (lazily)
NativeCodePtr exn_get_rth_throw_incompatible_class_change_exception();
+NativeCodePtr exn_get_rth_throw_illegal_state_exception();
+
//**** Various standard exception types
Class_Handle exn_get_class_cast_exception_type();
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h?rev=434076&r1=434075&r2=434076&view=diff
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h Wed Aug 23 09:48:41 2006
@@ -24,11 +24,9 @@
#include "jni_direct.h"
#include "jvmti.h"
-class VM_thread;
-
struct TIEventThread
{
- VM_thread *thread;
+ hythread_t thread;
TIEventThread *next;
};
@@ -81,11 +79,17 @@
/* Events functions */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void jvmti_send_vm_start_event(Global_Env *env, JNIEnv *jni_env);
void jvmti_send_vm_init_event(Global_Env *env);
void jvmti_send_compiled_method_load_event(Method *method);
void jvmti_send_dynamic_code_generated_event(const char *name, const void *address, jint length);
-void jvmti_send_contended_enter_or_entered_monitor_event(jobject obj, bool isEnter);
+VMEXPORT void jvmti_send_contended_enter_or_entered_monitor_event(jobject obj, int isEnter);
+VMEXPORT void jvmti_send_wait_monitor_event(jobject obj, jlong timeout);
+VMEXPORT void jvmti_send_waited_monitor_event(jobject obj, jboolean is_timed_out);
void jvmti_send_exception_event(jthrowable exn_object,
Method *method, jlocation location,
Method *catch_method, jlocation catch_location);
@@ -96,8 +100,12 @@
int classlen, unsigned char* classbytes,
int* newclasslen, unsigned char** newclass);
void jvmti_send_class_prepare_event(Class* clss);
-void jvmti_send_thread_start_end_event(int is_start);
+VMEXPORT void jvmti_send_thread_start_end_event(int is_start);
void jvmti_send_vm_death_event();
+
+#ifdef __cplusplus
+}
+#endif
/* External events functions */
VMEXPORT void jvmti_interpreter_exception_event_callback_call(void);
Modified: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/lock_manager.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/lock_manager.h?rev=434076&r1=434075&r2=434076&view=diff
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/lock_manager.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/lock_manager.h Wed Aug 23 09:48:41 2006
@@ -24,8 +24,7 @@
#ifndef _lock_manager_H_
#define _lock_manager_H_
-#include "open/vm_util.h" // for CriticalSection
-
+#include "open/vm_util.h"
#include "open/types.h"
#ifdef __cplusplus
@@ -50,7 +49,7 @@
bool _lock_enum_or_null (bool return_null_on_fail);
private:
- /*CRITICAL_SECTION*/ CriticalSection _critical_section;
+ hymutex_t lock;
};
@@ -70,11 +69,9 @@
extern Lock_Manager *p_jit_a_method_lock;
extern Lock_Manager *p_vtable_patch_lock;
extern Lock_Manager *p_meth_addr_table_lock;
-extern Lock_Manager *p_thread_lock;
// 20040224 Support for recording which methods (actually, CodeChunkInfo's) call which other methods.
extern Lock_Manager *p_method_call_lock;
-VMEXPORT extern Lock_Manager *p_gc_lock;
-extern Lock_Manager *p_tm_lock;
+extern Lock_Manager *p_handle_lock;
#endif // __cplusplus
#endif // _lock_manager_H_