You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by wj...@apache.org on 2007/05/25 15:51:50 UTC
svn commit: r541653 - in /harmony/enhanced/drlvm/trunk:
build/make/components/vm/ vm/gc_gen/src/common/ vm/gc_gen/src/mark_compact/
vm/include/open/ vm/tests/smoke/thread/ vm/thread/src/ vm/vmcore/src/thread/
Author: wjwashburn
Date: Fri May 25 06:51:49 2007
New Revision: 541653
URL: http://svn.apache.org/viewvc?view=rev&rev=541653
Log:
harmony-2742, monitor_deallocation_25.05.2007-2.patch is committed
build test2 passes on win32, win64, lin32 and lin64
Added:
harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/ManyThreadsTest.java
Modified:
harmony/enhanced/drlvm/trunk/build/make/components/vm/hythr.xml
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_pool.cpp
harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/los_extention_mark_scan.cpp
harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h
harmony/enhanced/drlvm/trunk/vm/include/open/vm_gc.h
harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def
harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp
harmony/enhanced/drlvm/trunk/vm/thread/src/thread_init.c
harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_basic.c
harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_monitors.c
harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_suspend.c
harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_thin_monitor.c
harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h
harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp
Modified: harmony/enhanced/drlvm/trunk/build/make/components/vm/hythr.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/build/make/components/vm/hythr.xml?view=diff&rev=541653&r1=541652&r2=541653
==============================================================================
--- harmony/enhanced/drlvm/trunk/build/make/components/vm/hythr.xml (original)
+++ harmony/enhanced/drlvm/trunk/build/make/components/vm/hythr.xml Fri May 25 06:51:49 2007
@@ -75,12 +75,9 @@
<select os="win" arch="em64t">
<defineset define="_EM64T_" />
</select>
- <!--
<select osfamily="unix">
- <compilerarg value="-Wno-deprecated" />
<compilerarg value="-fno-exceptions" />
</select>
- -->
<defineset define="APR_DECLARE_STATIC" />
</compiler>
@@ -96,6 +93,7 @@
<libset libs="${extra.apr.lib}"
dir="${extra.apr.libdir}" />
+
<select os="win">
<linkerarg value="/DEF:${src}/thread/src/hythr.def" />
@@ -106,7 +104,7 @@
</select>
<select os="lnx">
- <syslibset libs="rt" />
+ <syslibset libs="stdc++,rt" />
<linkerarg value="-Wl,-init" />
<linkerarg value="-Wl,hythread_library_init" />
<linkerarg value="-Wl,--version-script,${src}/thread/src/hythr.exp" />
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp?view=diff&rev=541653&r1=541652&r2=541653
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp Fri May 25 06:51:49 2007
@@ -326,12 +326,18 @@
#endif
}
+ //For_LOS_extend!
gc_space_tuner_reset(gc);
-
+
gc_assign_free_area_to_mutators(gc);
+ vm_reclaim_native_objs();
+
vm_resume_threads_after();
return;
}
+
+
+
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_pool.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_pool.cpp?view=diff&rev=541653&r1=541652&r2=541653
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_pool.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/mark_scan_pool.cpp Fri May 25 06:51:49 2007
@@ -36,6 +36,8 @@
static FORCE_INLINE void scan_object(Collector* collector, Partial_Reveal_Object *p_obj)
{
+ vm_notify_obj_alive( (void *)p_obj);
+
if( !object_has_ref_field(p_obj) ) return;
REF *p_ref;
Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/los_extention_mark_scan.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/los_extention_mark_scan.cpp?view=diff&rev=541653&r1=541652&r2=541653
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/los_extention_mark_scan.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/los_extention_mark_scan.cpp Fri May 25 06:51:49 2007
@@ -41,6 +41,7 @@
static FORCE_INLINE void scan_object(Collector* collector, Partial_Reveal_Object *p_obj)
{
+ vm_notify_obj_alive( (void *)p_obj);
if( !object_has_ref_field(p_obj) ) return;
REF *p_ref;
Modified: harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h?view=diff&rev=541653&r1=541652&r2=541653
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h Fri May 25 06:51:49 2007
@@ -306,6 +306,9 @@
hythread_t VMCALL hythread_thin_monitor_get_owner(hythread_thin_monitor_t *lockword);
IDATA VMCALL hythread_thin_monitor_get_recursion(hythread_thin_monitor_t *lockword);
+void VMCALL hythread_native_resource_is_live(U_32);
+void VMCALL hythread_reclaim_resources();
+
//@}
/** @name State query
*/
Modified: harmony/enhanced/drlvm/trunk/vm/include/open/vm_gc.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/vm_gc.h?view=diff&rev=541653&r1=541652&r2=541653
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/vm_gc.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/vm_gc.h Fri May 25 06:51:49 2007
@@ -159,6 +159,14 @@
*/
VMEXPORT Boolean verify_object_header(void *ptr);
+/**
+ * Routines to support lifecycle management of resources associated
+ * with a java object
+ */
+
+VMEXPORT void vm_notify_obj_alive(void *);
+VMEXPORT void vm_reclaim_native_objs();
+
/*
* *****
Added: harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/ManyThreadsTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/ManyThreadsTest.java?view=auto&rev=541653
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/ManyThreadsTest.java (added)
+++ harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/ManyThreadsTest.java Fri May 25 06:51:49 2007
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+package thread;
+
+public class ManyThreadsTest implements Runnable{
+ private static final int MAX_ITERATION_NUMBER = 100000;
+ private static final int PRINT_ITERATION_NUMBER = 10000;
+ public static final int MAX_THREADS_COUNTITY = 100;
+
+ private static int threadCounters[] = new int[MAX_THREADS_COUNTITY];
+ private static Thread threads[] = new Thread[MAX_THREADS_COUNTITY];
+
+ public static void main(String args[]) throws Exception {
+
+ for (int i = 0; i < MAX_ITERATION_NUMBER;) {
+ ////System.out.println("Iteration = " + i);
+
+ for (int l = i + PRINT_ITERATION_NUMBER; i < l; ++i) {
+ int t = i % MAX_THREADS_COUNTITY;
+
+ if (null != threads[t]){
+ threads[t].join();
+ }
+ threads[t] = new Thread(new ManyThreadsTest(t));
+ threads[t].start();
+ }
+ allocObjs();
+ }
+
+ System.out.println("PASS");
+ }
+
+ private int index;
+
+ public ManyThreadsTest(int index){
+ this.index = index;
+ }
+
+ public void run(){
+ threadCounters[index]++;
+ }
+
+ public static void allocObjs() {
+ for (int xx = 0; xx < 100; xx++) {
+ int ia [] = new int[1024 * 1024];
+ }
+ }
+}
+
Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def?view=diff&rev=541653&r1=541652&r2=541653
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def Fri May 25 06:51:49 2007
@@ -86,6 +86,8 @@
hythread_thin_monitor_notify_all
hythread_thin_monitor_destroy
hythread_thin_monitor_get_owner
+hythread_native_resource_is_live
+hythread_reclaim_resources
hysem_post
hysem_wait
Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp?view=diff&rev=541653&r1=541652&r2=541653
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp Fri May 25 06:51:49 2007
@@ -87,6 +87,9 @@
hythread_thin_monitor_notify_all;
hythread_thin_monitor_destroy;
hythread_thin_monitor_get_owner;
+hythread_native_resource_is_live;
+hythread_reclaim_resources;
+
hythread_add_task;
hythread_get_function_pointer;
hythread_get_data_pointer;
Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_init.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_init.c?view=diff&rev=541653&r1=541652&r2=541653
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_init.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_init.c Fri May 25 06:51:49 2007
@@ -41,7 +41,6 @@
//Thread manager global lock
hymutex_t TM_START_LOCK;
static int TM_INITIALIZED = 0;
-hymutex_t FAT_MONITOR_TABLE_LOCK;
#define GLOBAL_MONITOR_NAME "global_monitor"
hythread_monitor_t p_global_monitor;
@@ -49,9 +48,6 @@
hythread_group_t TM_DEFAULT_GROUP;
hythread_group_t group_list;
-hythread_monitor_t *lock_table = NULL;
-int table_size = 8024;
-
IDATA groups_count;
static IDATA init_group_list();
@@ -157,9 +153,7 @@
assert(status == TM_ERROR_NONE);
status = hymutex_create(&TM_START_LOCK, TM_MUTEX_NESTED);
assert(status == TM_ERROR_NONE);
- status = hymutex_create(&FAT_MONITOR_TABLE_LOCK, TM_MUTEX_NESTED);
- assert(status == TM_ERROR_NONE);
-
+
status = init_group_list();
assert(status == TM_ERROR_NONE);
@@ -172,10 +166,7 @@
lib->nondaemon_thread_count = 0;
status = hycond_create(&lib->nondaemon_thread_cond);
assert(status == TM_ERROR_NONE);
-
- lock_table = (hythread_monitor_t *)malloc(sizeof(hythread_monitor_t)*table_size);
- assert(lock_table);
-
+
// init global monitor
status=hythread_monitor_init_with_name(&p_global_monitor, 0, "Thread Global Monitor");
assert(status == TM_ERROR_NONE);
@@ -278,6 +269,7 @@
// Initial group, does not contain any actual group, but serves
//as a head and a tail of this list;
hythread_group_t dummy;
+
//this group will exist as long as TM lives, so it's ok to have
//the same pool for them
@@ -288,7 +280,23 @@
dummy->next = dummy->prev = dummy;
group_list = dummy;
groups_count = 0;
-
+
+ lock_table = (HyFatLockTable *) malloc (sizeof(HyFatLockTable));
+ lock_table->table = (hythread_monitor_t *)calloc(INITIAL_FAT_TABLE_ENTRIES,
+ sizeof(hythread_monitor_t));
+ lock_table->live_objs = (unsigned char *)calloc(INITIAL_FAT_TABLE_ENTRIES,
+ sizeof(unsigned char));
+ lock_table->size = INITIAL_FAT_TABLE_ENTRIES;
+ lock_table->array_cursor = 0;
+
+ assert (lock_table);
+ assert (lock_table->table);
+ assert (lock_table->live_objs);
+
+ if (hymutex_create(&lock_table->mutex, APR_THREAD_MUTEX_NESTED)) {
+ return TM_ERROR_OUT_OF_MEMORY;
+ }
+
return TM_ERROR_NONE;
}
@@ -312,8 +320,17 @@
cur = cur->next;
}
}
+
+ free(lock_table->live_objs);
+ free(lock_table->table);
+
+ status = hymutex_destroy(&lock_table->mutex);
+
+ free(lock_table);
+
status2=hythread_global_unlock();
if (status2 != TM_ERROR_NONE) return status2;
+
return status;
}
Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_basic.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_basic.c?view=diff&rev=541653&r1=541652&r2=541653
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_basic.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_basic.c Fri May 25 06:51:49 2007
@@ -24,12 +24,14 @@
#include <open/hythread_ext.h>
#include <apr_atomic.h>
#include "open/thread_externals.h"
-#include "thread_private.h"
-#include "jni.h"
#undef LOG_DOMAIN
#define LOG_DOMAIN "tm.java"
+#include "thread_private.h"
+#include "jni.h"
+
+
void stop_callback(void);
jmethodID getRunMethod(JNIEnv *env, jthread java_thread);
IDATA increase_nondaemon_threads_count(hythread_t self);
@@ -83,7 +85,7 @@
jvmti_thread->jenv = jni_env;
jvmti_thread->daemon = data->daemon;
- TRACE(("TM: Java thread started: id=%d OS_handle=%p", native_thread->thread_id, apr_os_thread_current()));
+ TRACE( ("TM: Java thread started: id=%d OS_handle=%p", native_thread->thread_id, apr_os_thread_current()) );
if (!jvmti_thread->daemon) {
increase_nondaemon_threads_count(native_thread);
Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_monitors.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_monitors.c?view=diff&rev=541653&r1=541652&r2=541653
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_monitors.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_monitors.c Fri May 25 06:51:49 2007
@@ -33,6 +33,7 @@
void set_contended_monitor(jobject monitor);
void set_wait_monitor(jobject monitor);
+
/**
* Initializes Java monitor.
*
@@ -286,6 +287,7 @@
* @param[in] nanos time to wait (in nanoseconds)
* @sa java.lang.Object.wait()
*/
+
IDATA VMCALL jthread_monitor_timed_wait(jobject monitor, jlong millis, jint nanos) {
hythread_thin_monitor_t *lockword;
IDATA status;
@@ -293,7 +295,6 @@
apr_time_t wait_begin;
jvmti_thread_t tm_java_thread;
int disable_count;
- ///////
assert(monitor);
@@ -412,7 +413,6 @@
return;
}
}
- //assert(0); monitor - it is no valid monitor
}
void set_contended_monitor(jobject monitor){
Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_suspend.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_suspend.c?view=diff&rev=541653&r1=541652&r2=541653
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_suspend.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_suspend.c Fri May 25 06:51:49 2007
@@ -275,6 +275,7 @@
void VMCALL hythread_resume(hythread_t thread)
{
int count;
+ hythread_t self = tm_self_tls;
TRACE(("start resume, self: %p, thread: %p, "
"suspend_count: %d, request: %d", self, thread,
Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_thin_monitor.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_thin_monitor.c?view=diff&rev=541653&r1=541652&r2=541653
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_thin_monitor.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_thin_monitor.c Fri May 25 06:51:49 2007
@@ -57,6 +57,13 @@
#define RECURSION_DEC(lockword_ptr, lockword) (*lockword_ptr=lockword - (1<<11))
#define MAX_RECURSION 31
+
+/*
+ * Lock table which holds the omapping between LockID and fat lock (OS fat_monitor) pointer.
+ */
+
+HyFatLockTable *lock_table = NULL;
+
IDATA owns_thin_lock(hythread_t thread, I_32 lockword) {
IDATA this_id = thread->thread_id;
assert(!IS_FAT_LOCK(lockword));
@@ -69,18 +76,31 @@
}
void set_fat_lock_id(hythread_thin_monitor_t *lockword_ptr, IDATA monitor_id) {
- I_32 lockword = *lockword_ptr;
+ U_32 lockword = *lockword_ptr;
#ifdef LOCK_RESERVATION
assert(!IS_RESERVED(lockword));
#endif
+ assert((U_32)monitor_id < lock_table->size);
lockword&=0x7FF;
lockword|=(monitor_id << 11) | 0x80000000;
*lockword_ptr=lockword;
apr_memory_rw_barrier();
}
+IDATA get_fat_lock_id(hythread_thin_monitor_t *lockword_ptr) {
+ // this method steals the bit mask from set_fat_lock_id above
+ // get_fat_lock() and set_fat_lock need cleaning up
+ // the bit masks should be replaced with "#define ..."
+ U_32 lockword = *lockword_ptr;
+ assert(lockword & 0x80000000); //fat lock bit better be set
+ lockword &= 0x7fFFffFF; // throw away the fat lock bit
+ lockword = lockword >> 11;
+ assert(lockword < lock_table->size);
+ return lockword;
+}
+
IDATA is_fat_lock(hythread_thin_monitor_t lockword) {
- return IS_FAT_LOCK(lockword);
+ return IS_FAT_LOCK(lockword);
}
//forward declaration
@@ -108,8 +128,8 @@
* Unreserves the lock already owned by this thread
*/
void unreserve_self_lock(hythread_thin_monitor_t *lockword_ptr) {
- I_32 lockword = *lockword_ptr;
- I_32 lockword_new;
+ U_32 lockword = *lockword_ptr;
+ U_32 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));
@@ -132,17 +152,17 @@
* Used lockword
*/
IDATA unreserve_lock(hythread_thin_monitor_t *lockword_ptr) {
- I_32 lockword = *lockword_ptr;
- I_32 lockword_new;
+ U_32 lockword = *lockword_ptr;
+ U_32 lockword_new;
uint16 lock_id;
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;
- }*/
+ if (status !=TM_ERROR_NONE) {
+ return status;
+ }*/
if (IS_FAT_LOCK(lockword)) {
return TM_ERROR_NONE;
@@ -161,7 +181,7 @@
assert(owner != hythread_self());
status=hythread_suspend_other(owner);
if (status !=TM_ERROR_NONE) {
- return status;
+ return status;
}
}
// prepare new unreserved lockword and try to CAS it with old one.
@@ -177,7 +197,7 @@
lockword_new = lockword_new & 0x0000ffff;
}
if (lockword == apr_atomic_cas32 (((volatile apr_uint32_t*) lockword_ptr),
- (apr_uint32_t) lockword_new, lockword)) {
+ (apr_uint32_t) lockword_new, lockword)) {
TRACE(("unreserved lock"));
break;
}
@@ -231,12 +251,12 @@
* @param[in] lockword_ptr monitor addr
*/
IDATA hythread_thin_monitor_try_enter(hythread_thin_monitor_t *lockword_ptr) {
- I_32 lockword;
+ U_32 lockword;
// warkaround strange intel compiler bug
- #if defined (__INTEL_COMPILER) && defined (LINUX)
+#if defined (__INTEL_COMPILER) && defined (LINUX)
volatile
- #endif
- IDATA this_id = tm_self_tls->thread_id;
+#endif
+ IDATA this_id = tm_self_tls->thread_id;
IDATA lock_id;
IDATA status;
hythread_monitor_t fat_monitor;
@@ -283,7 +303,7 @@
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)) {
+ (apr_uint16_t) this_id, 0)) {
#ifdef SPIN_COUNT
continue;
@@ -295,43 +315,43 @@
#ifdef LOCK_RESERVATION
//lockword = *lockword_ptr; // this reloading of lockword may be odd, need to investigate;
if (IS_RESERVED(lockword)) {
- TRACE(("initially reserve lock %x count: %d ", *lockword_ptr, init_reserve_cout++));
- RECURSION_INC(lockword_ptr, *lockword_ptr);
+ TRACE(("initially 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);
+ // 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;
- }
+ if (status == TM_ERROR_EBUSY) {
+ continue;
+ }
#endif
- return status;
- }
+ return status;
+ }
#ifdef LOCK_RESERVATION
// unreserved busy lock
- else if (IS_RESERVED(lockword)) {
- status = unreserve_lock(lockword_ptr);
- if (status != TM_ERROR_NONE) {
+ else if (IS_RESERVED(lockword)) {
+ status = unreserve_lock(lockword_ptr);
+ if (status != TM_ERROR_NONE) {
#ifdef SPIN_COUNT
- if (status == TM_ERROR_EBUSY) {
- continue;
- }
+ if (status == TM_ERROR_EBUSY) {
+ continue;
+ }
#endif //SPIN_COUNT
- return status;
- }
- assert(!IS_RESERVED(*lockword_ptr));
- return hythread_thin_monitor_try_enter(lockword_ptr);
- }
+ return status;
+ }
+ assert(!IS_RESERVED(*lockword_ptr));
+ return hythread_thin_monitor_try_enter(lockword_ptr);
+ }
#endif
#ifdef SPIN_COUNT
hythread_yield();
@@ -384,7 +404,7 @@
* @param[in] lockword_ptr monitor addr
*/
IDATA VMCALL hythread_thin_monitor_exit(hythread_thin_monitor_t *lockword_ptr) {
- I_32 lockword = *lockword_ptr;
+ U_32 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);
@@ -404,7 +424,7 @@
//TRACE(("recursion_dec: 0x%x", *lockword_ptr));
}
//TRACE(("unlocked: 0x%x id: %d\n", *lockword_ptr, THREAD_ID(*lockword_ptr)));
- //hythread_safe_point();
+ //hythread_safe_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));
@@ -419,7 +439,7 @@
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;
- I_32 lockword = *lockword_ptr;
+ U_32 lockword = *lockword_ptr;
hythread_monitor_t fat_monitor;
if (!IS_FAT_LOCK(lockword)) {
@@ -501,9 +521,9 @@
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);
+ 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)) {
@@ -522,9 +542,9 @@
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);
+ 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)) {
@@ -543,15 +563,13 @@
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);
+ 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
*/
@@ -559,14 +577,14 @@
hythread_monitor_t fat_monitor;
IDATA status;
IDATA fat_monitor_id;
- I_32 lockword;
+ U_32 lockword;
int i;
- status=hymutex_lock(&FAT_MONITOR_TABLE_LOCK);
+ status=hymutex_lock(&lock_table->mutex);
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);
+ status = hymutex_unlock(&lock_table->mutex);
assert(status == TM_ERROR_NONE);
return locktable_get_fat_monitor(FAT_LOCK_ID(lockword));
}
@@ -587,7 +605,7 @@
assert(status == TM_ERROR_NONE);
status = hythread_monitor_enter(fat_monitor);
if (status != TM_ERROR_NONE) {
- hymutex_unlock(&FAT_MONITOR_TABLE_LOCK);
+ hymutex_unlock(&lock_table->mutex);
return NULL;
}
@@ -603,7 +621,7 @@
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);
+ status=hymutex_unlock(&lock_table->mutex);
assert(status == TM_ERROR_NONE);
#ifdef LOCK_RESERVATION
assert(!IS_RESERVED(*lockword_ptr));
@@ -617,28 +635,19 @@
* 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
+ /*
+ ;;// 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
-
-extern int table_size;
-extern hythread_monitor_t *lock_table;
-int fat_monitor_count = 1;
// Lock table implementation
@@ -649,42 +658,137 @@
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();
+
+ assert(lock_id >=0 && (U_32)lock_id < lock_table->size);
+ hymutex_lock(&lock_table->mutex);
+ fat_monitor = lock_table->table[lock_id];
+ hymutex_unlock(&lock_table->mutex);
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++;
- if (id >= table_size) {
- hythread_suspend_all(NULL, NULL);
- table_size = table_size*2;
- lock_table = (hythread_monitor_t *)realloc(lock_table, sizeof(hythread_monitor_t)*table_size);
- assert(lock_table);
- apr_memory_rw_barrier();
- hythread_resume_all(NULL);
- }
-
- lock_table[id] = fat_monitor;
- //hythread_global_unlock();
- return id;
-}
+ U_32 i = 0;
+ int mon_index;
+ short free_slot_found = 0;
+
+ if (lock_table == 0) {
+ DIE (("Lock table not initialized!"));
+ }
+
+
+ hymutex_lock(&lock_table->mutex);
+ for(i =0; i < lock_table->size; i++) {
+ if (lock_table->table[lock_table->array_cursor] == 0) {
+ assert(lock_table->live_objs[lock_table->array_cursor] == 0);
+ lock_table->table[lock_table->array_cursor] = fat_monitor;
+ free_slot_found = 1;
+ break;
+ }
+ lock_table->array_cursor++;
+ if (lock_table->array_cursor == lock_table->size)
+ lock_table->array_cursor = 0;
+ }
+
+ if(!free_slot_found) {
+ int old_size;
+
+ old_size = lock_table->size;
+ lock_table->size += INITIAL_FAT_TABLE_ENTRIES;
+ lock_table->table = realloc(lock_table->table,
+ lock_table->size * sizeof(hythread_monitor_t));
+ assert(lock_table->table);
+
+ lock_table->live_objs = realloc(lock_table->live_objs,
+ lock_table->size * sizeof(unsigned char));
+ assert(lock_table->live_objs);
+
+ memset(lock_table->table + old_size, 0,
+ INITIAL_FAT_TABLE_ENTRIES * sizeof(hythread_monitor_t));
+ memset(lock_table->live_objs + old_size, 0,
+ INITIAL_FAT_TABLE_ENTRIES * sizeof(unsigned char));
+
+ lock_table->array_cursor = old_size;
+ lock_table->table[lock_table->array_cursor] = fat_monitor;
+
+ }
+ mon_index = lock_table->array_cursor;
+ hymutex_unlock(&lock_table->mutex);
+ return mon_index;
+}
+
+// flag that is set when major collection happens
+static unsigned char live_objs_were_reported = 0;
+
+
+void VMCALL hythread_native_resource_is_live(U_32 lockword)
+{
+ IDATA index = 0;
+ index = get_fat_lock_id( (hythread_thin_monitor_t *) &lockword);
+ hymutex_lock(&lock_table->mutex);
+ lock_table->live_objs[index] = 1; // mark the fat lock entry as still alive
+ live_objs_were_reported = 1;
+ hymutex_unlock(&lock_table->mutex);
+}
+
+void VMCALL hythread_reclaim_resources()
+{
+ U_32 i = 0;
+
+#ifdef DEBUG_NATIVE_RESOURCE_COLLECTION
+ int old_slots_occupied = 0;
+ int new_slots_occupied = 0;
+
+ for (i < lock_table->size)
+ if (lock_table->table[i])
+ old_slots_occupied++;
+#endif
+
+ hymutex_lock(&lock_table->mutex);
+ // If major collection didn't happen, do nothing
+ if (!live_objs_were_reported) {
+ hymutex_unlock(&lock_table->mutex);
+ return;
+ }
+ // reset the flag (major collection happened)
+ live_objs_were_reported = 0;
+
+ for(i = 0; i < lock_table->size; i++) {
+ if (lock_table->live_objs[i]) {
+ assert(lock_table->table[i]);
+#ifdef DEBUG_NATIVE_RESOURCE_COLLECTION
+ new_slots_occupied++;
+#endif
+
+ // reset the live array for the next major GC cycle
+ lock_table->live_objs[i] = 0;
+ } else {
+ if (lock_table->table[i]) {
+ hythread_monitor_destroy(lock_table->table[i]);
+ lock_table->table[i] = 0;
+ }
+ }
+ }
+ hymutex_unlock(&lock_table->mutex);
+#ifdef DEBUG_NATIVE_RESOURCE_COLLECTION
+ TRACE(("hythread_reclaim_resources(): old = %d, new = %d\n",
+ old_slots_occupied,
+ new_slots_occupied));
+#endif
+}
/*
* Deletes the entry in the lock table with the given lock_id
*/
-hythread_monitor_t locktable_delete_entry(int 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;
+ DIE(("shouldn't get here"));
+ assert(lock_id >=0 && (U_32)lock_id < lock_table->size);
+ m = lock_table->table[lock_id];
+ lock_table->table[lock_id] = NULL;
return m;
}
@@ -694,23 +798,24 @@
* @param[in] lockword_ptr monitor addr
*/
hythread_t VMCALL hythread_thin_monitor_get_owner(hythread_thin_monitor_t *lockword_ptr) {
- I_32 lockword;
+ U_32 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
+ // find fat_monitor in lock table
+ fat_monitor = locktable_get_fat_monitor(FAT_LOCK_ID(lockword));
return fat_monitor->owner;
}
if (THREAD_ID(lockword)== 0) {
- return NULL;
+ return NULL;
}
#ifdef LOCK_RESERVATION
if (RECURSION(lockword)==0 && IS_RESERVED(lockword)) {
- return NULL;
+ return NULL;
}
#endif
return hythread_get_thread(THREAD_ID(lockword));
@@ -722,13 +827,14 @@
* @param[in] lockword_ptr monitor addr
*/
IDATA VMCALL hythread_thin_monitor_get_recursion(hythread_thin_monitor_t *lockword_ptr) {
- I_32 lockword;
+ U_32 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
+ // find fat_monitor in lock table
+ fat_monitor = locktable_get_fat_monitor(FAT_LOCK_ID(lockword));
return fat_monitor->recursion_count+1;
}
if (THREAD_ID(lockword) == 0) {
@@ -736,7 +842,7 @@
}
#ifdef LOCK_RESERVATION
if (IS_RESERVED(lockword)) {
- return RECURSION(lockword);
+ return RECURSION(lockword);
}
#endif
return RECURSION(lockword)+1;
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=541653&r1=541652&r2=541653
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h Fri May 25 06:51:49 2007
@@ -37,8 +37,14 @@
#endif // __linux__
// temporary remove logging
+//#define TRACE(a) //printf a; printf("\n")
+
+#ifdef __linux__
+#include "clog.h"
+#else
#define TRACE(a) //printf a; printf("\n")
-//#include "clog.h"
+#define DIE(A) //exit(55);
+#endif
// FIXME move to the global header, add error converter
#define RET_ON_ERROR(stat) if (stat) { return -1; }
@@ -47,6 +53,8 @@
#define MAX_OWNED_MONITOR_NUMBER 200 //FIXME: switch to dynamic resize
#define FAST_LOCAL_STORAGE_SIZE 10
+#define INITIAL_FAT_TABLE_ENTRIES 16*1024 //make this table exapandible if workloads show it is necessary
+
#if !defined (_IPF_)
//use lock reservation
#define LOCK_RESERVATION
@@ -530,6 +538,31 @@
hymutex_t mutex;
} HySemaphore;
+
+/*
+ * Lock table which holds the mapping between LockID and fat lock
+ * (OS fat_monitor) pointer.
+ */
+
+typedef struct HyFatLockTable {
+ // locktable itself
+ hythread_monitor_t *table;
+
+ // mutex guarding locktable
+ hymutex_t mutex;
+
+ // table of live objects (updated during each major GC)
+ unsigned char *live_objs;
+
+ // size of locktable
+ U_32 size;
+
+ // used to scan the lock table for the next available entry
+ U_32 array_cursor;
+
+} HyFatLockTable;
+
+
// Global variables
extern hythread_group_t group_list; // list of thread groups
@@ -542,6 +575,8 @@
extern int max_group_index; // max number of groups
extern int total_started_thread_count; // Total started thread counter.
+
+extern HyFatLockTable *lock_table;
#define THREAD_ID_SIZE 16 //size of thread ID in bits. Also defines max number of threads
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp?view=diff&rev=541653&r1=541652&r2=541653
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp Fri May 25 06:51:49 2007
@@ -91,6 +91,8 @@
#include "../m2n_ia32_internal.h"
#endif
+#define IS_FAT_LOCK(lockword) (lockword >> 31)
+
extern struct JNINativeInterface_ jni_vtable;
struct vmthread_dummies {
@@ -309,3 +311,17 @@
vm_jthread_set_tm_data(jthread java_thread, NULL);
*/
}
+
+void vm_notify_obj_alive(void *p_obj)
+{
+ if (IS_FAT_LOCK(((ManagedObject *)p_obj)->get_obj_info())) {
+ uint32 xx = ((ManagedObject *)p_obj)->get_obj_info();
+ hythread_native_resource_is_live(xx);
+ }
+}
+
+void vm_reclaim_native_objs()
+{
+ hythread_reclaim_resources();
+}
+