Index: vm/include/open/thread_externals.h =================================================================== --- vm/include/open/thread_externals.h (revision 542228) +++ vm/include/open/thread_externals.h (working copy) @@ -129,6 +129,21 @@ VMEXPORT void *vm_allocate_thread_dummies(JavaVM *java_vm); +/** + * A structure for thread manager properties + * There is the only yet. Others to be added here. + */ +struct tm_props { + int use_soft_unreservation; +}; + +#if !defined(_TM_PROP_EXPORT) +extern VMIMPORT struct tm_props *tm_properties; +#else +struct tm_props *tm_properties = NULL; +#endif + + #ifdef __cplusplus } #endif Index: vm/vmcore/src/init/vm_properties.cpp =================================================================== --- vm/vmcore/src/init/vm_properties.cpp (revision 542228) +++ vm/vmcore/src/init/vm_properties.cpp (working copy) @@ -273,6 +273,7 @@ properties.set_new("vm.jvmti.compiled_method_load.inlined", "false"); properties.set_new("vm.bootclasspath.appendclasspath", "false"); properties.set_new("vm.dlls", PORT_DSO_NAME(GC_DLL)); + properties.set_new("thread.soft_unreservation", "false"); int n_api_dll_files = sizeof(api_dll_files) / sizeof(char *); /* Index: vm/vmcore/src/init/parse_arguments.cpp =================================================================== --- vm/vmcore/src/init/parse_arguments.cpp (revision 542228) +++ vm/vmcore/src/init/parse_arguments.cpp (working copy) @@ -242,6 +242,8 @@ " Report inlined methods with JVMTI_EVENT_COMPILED_METHOD_LOAD. Makes sense for optimizing jit.\n" " vm.bootclasspath.appendclasspath (default FALSE):\n" " Append classpath to the bootclasspath.\n" + " thread.soft_unreservation (default FALSE):\n" + " Use soft unreservation scheme.\n" "\nOther properties:\n\n" " vm.boot.library.path:\n" " List of directories which contain additional dynamic libraries to load into VM.\n" Index: vm/vmcore/src/init/vm_init.cpp =================================================================== --- vm/vmcore/src/init/vm_init.cpp (revision 542228) +++ vm/vmcore/src/init/vm_init.cpp (working copy) @@ -665,6 +665,15 @@ initialize_properties(vm_env); + tm_properties = (struct tm_props*) STD_MALLOC(sizeof(struct tm_props)); + + if (!tm_properties) { + LWARN(30, "failed to allocate mem for tp properties"); + return JNI_ERR; + } + + tm_properties->use_soft_unreservation = get_boolean_property("thread.soft_unreservation", FALSE, VM_PROPERTIES); + parse_vm_arguments(vm_env); vm_env->verify = get_boolean_property("vm.use_verifier", TRUE, VM_PROPERTIES); Index: vm/thread/src/hythr.exp =================================================================== --- vm/thread/src/hythr.exp (revision 542228) +++ vm/thread/src/hythr.exp (working copy) @@ -167,7 +167,7 @@ array_delete; array_get; get_java_thread_group; - +tm_properties; Java_org_apache_harmony_drlvm_thread_ThreadHelper_getThreadIdOffset; Index: vm/thread/src/hythr.def =================================================================== --- vm/thread/src/hythr.def (revision 542228) +++ vm/thread/src/hythr.def (working copy) @@ -155,5 +155,5 @@ array_get get_java_thread_group - +tm_properties; Java_org_apache_harmony_drlvm_thread_ThreadHelper_getThreadIdOffset Index: vm/thread/src/thread_native_thin_monitor.c =================================================================== --- vm/thread/src/thread_native_thin_monitor.c (revision 542228) +++ vm/thread/src/thread_native_thin_monitor.c (working copy) @@ -22,6 +22,7 @@ #undef LOG_DOMAIN #define LOG_DOMAIN "tm.locks" +#define _TM_PROP_EXPORT #include #include @@ -147,6 +148,7 @@ assert(!IS_RESERVED(*lockword_ptr)); TRACE(("unreserved self")); } + /* * Used lockword @@ -157,6 +159,8 @@ uint16 lock_id; hythread_t owner; IDATA status; + I_32 append; + // trylock used to prevent cyclic suspend deadlock // the java_monitor_enter calls safe_point between attempts. /*status = hymutex_trylock(&TM_LOCK); @@ -179,21 +183,43 @@ assert(owner); assert(hythread_get_id(owner) == lock_id); assert(owner != hythread_self()); + if(owner->state& + ( TM_THREAD_STATE_TERMINATED| + TM_THREAD_STATE_WAITING| + TM_THREAD_STATE_WAITING_INDEFINITELY| + TM_THREAD_STATE_WAITING_WITH_TIMEOUT| + TM_THREAD_STATE_SLEEPING| + TM_THREAD_STATE_SUSPENDED| + TM_THREAD_STATE_IN_MONITOR_WAIT ) + ) { + append = 0; + } else { + append = RESERVED_BITMASK; + } + status=hythread_suspend_other(owner); if (status !=TM_ERROR_NONE) { return status; } + } else { + append = 0; } + + if(!tm_properties || !tm_properties->use_soft_unreservation) { + append = RESERVED_BITMASK; + } + // 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) { + lockword_new = (lockword | RESERVED_BITMASK); assert(RECURSION(lockword) > 0); assert(RECURSION(lockword_new) > 0); RECURSION_DEC(&lockword_new, lockword_new); } else { + lockword_new = (lockword | append); lockword_new = lockword_new & 0x0000ffff; } if (lockword == apr_atomic_cas32 (((volatile apr_uint32_t*) lockword_ptr), @@ -220,8 +246,8 @@ // To avoid race condition between checking two different // conditions inside of assert, the lockword contents has to be // loaded before checking. - lockword = *lockword_ptr; - assert(IS_FAT_LOCK(lockword) || !IS_RESERVED(lockword)); +// lockword = *lockword_ptr; +// assert(IS_FAT_LOCK(lockword) || !IS_RESERVED(lockword)); return TM_ERROR_NONE; } #else