Index: vmcore/include/finalizer_thread.h =================================================================== --- vmcore/include/finalizer_thread.h (revision 527889) +++ vmcore/include/finalizer_thread.h (working copy) @@ -66,9 +66,11 @@ extern void finalizer_threads_init(JavaVM *java_vm); extern void finalizer_shutdown(Boolean start_finalization_on_exit); extern void activate_finalizer_threads(Boolean wait); -extern void vmmemory_manager_runfinalization(void); +inline void native_sync_run_finalization(void) +{ activate_finalizer_threads(TRUE); }; + extern void vm_heavy_finalizer_resume_mutator(void); extern unsigned int cpu_num_bits; Index: vmcore/include/ref_enqueue_thread.h =================================================================== --- vmcore/include/ref_enqueue_thread.h (revision 527889) +++ vmcore/include/ref_enqueue_thread.h (working copy) @@ -33,13 +33,19 @@ typedef struct Ref_Enqueue_Thread_Info { hysem_t pending_sem; + hycond_t end_cond; // ref enqueue end condition variable + hymutex_t end_mutex; // ref enqueue end mutex Boolean shutdown; volatile unsigned int thread_attached; + volatile unsigned int end_waiting_num; // thread num waiting for finalization end }Ref_Enqueue_Thread_Info; extern void ref_enqueue_thread_init(JavaVM *java_vm); extern void ref_enqueue_shutdown(void); -extern void activate_ref_enqueue_thread(void); +extern void activate_ref_enqueue_thread(Boolean wait); +inline void native_sync_enqueue_references(void) +{ activate_ref_enqueue_thread(TRUE); }; + #endif // _REF_ENQUEUE_THREAD_H_ Index: vmcore/src/init/finalize.cpp =================================================================== --- vmcore/src/init/finalize.cpp (revision 527889) +++ vmcore/src/init/finalize.cpp (working copy) @@ -674,14 +674,14 @@ void vm_activate_ref_enqueue_thread() { if(get_native_ref_enqueue_thread_flag()) - activate_ref_enqueue_thread(); + activate_ref_enqueue_thread(FALSE); } void vm_enqueue_references() { /* BEGIN: modified for NATIVE REFERENCE ENQUEUE THREAD */ if(get_native_ref_enqueue_thread_flag()) - activate_ref_enqueue_thread(); + activate_ref_enqueue_thread(FALSE); else references_to_enqueue.enqueue_references(); /* END: modified for NATIVE REFERENCE ENQUEUE THREAD */ Index: vmcore/src/init/finalizer_thread.cpp =================================================================== --- vmcore/src/init/finalizer_thread.cpp (revision 527889) +++ vmcore/src/init/finalizer_thread.cpp (working copy) @@ -179,11 +179,6 @@ hycond_notify_all(&fin_thread_info->end_cond); } -void vmmemory_manager_runfinalization(void) -{ - activate_finalizer_threads(TRUE); -} - static void wait_pending_finalizer(void) { IDATA stat = hysem_wait(fin_thread_info->pending_sem); Index: vmcore/src/init/ref_enqueue_thread.cpp =================================================================== --- vmcore/src/init/ref_enqueue_thread.cpp (revision 527889) +++ vmcore/src/init/ref_enqueue_thread.cpp (working copy) @@ -52,6 +52,11 @@ IDATA status = hysem_create(&ref_thread_info->pending_sem, 0, REF_ENQUEUE_THREAD_NUM); assert(status == TM_ERROR_NONE); + status = hycond_create(&ref_thread_info->end_cond); + assert(status == TM_ERROR_NONE); + status = hymutex_create(&ref_thread_info->end_mutex, TM_MUTEX_DEFAULT); + assert(status == TM_ERROR_NONE); + void **args = (void **)STD_MALLOC(sizeof(void *)); args[0] = (void *)java_vm; status = hythread_create(NULL, 0, REF_ENQUEUE_THREAD_PRIORITY, 0, (hythread_entrypoint_t)ref_enqueue_thread_func, args); @@ -63,7 +68,7 @@ void ref_enqueue_shutdown(void) { ref_thread_info->shutdown = TRUE; - activate_ref_enqueue_thread(); + activate_ref_enqueue_thread(FALSE); } static uint32 atomic_inc32(volatile apr_uint32_t *mem) @@ -79,17 +84,41 @@ { atomic_dec32(&ref_thread_info->thread_attached); } static void wait_ref_thread_attached(void) -{ while(ref_thread_info->thread_attached == 0); } +{ while(ref_thread_info->thread_attached < REF_ENQUEUE_THREAD_NUM); } void wait_native_ref_thread_detached(void) { while(ref_thread_info->thread_attached); } -void activate_ref_enqueue_thread(void) +static void wait_ref_enqueue_end(void) { + hymutex_lock(&ref_thread_info->end_mutex); + unsigned int ref_num = vm_get_references_quantity(); + do { + unsigned int wait_time = ref_num + 100; + atomic_inc32(&ref_thread_info->end_waiting_num); + IDATA status = hycond_wait_timed(&ref_thread_info->end_cond, &ref_thread_info->end_mutex, (I_64)wait_time, 0); + atomic_dec32(&ref_thread_info->end_waiting_num); + if(status != TM_ERROR_NONE) break; + ref_num = vm_get_references_quantity(); + } while(ref_num); + hymutex_unlock(&ref_thread_info->end_mutex); +} + +void activate_ref_enqueue_thread(Boolean wait) +{ IDATA stat = hysem_set(ref_thread_info->pending_sem, REF_ENQUEUE_THREAD_NUM); assert(stat == TM_ERROR_NONE); + + if(wait) + wait_ref_enqueue_end(); } +static void notify_ref_enqueue_end(void) +{ + if(vm_get_references_quantity()==0) + hycond_notify_all(&ref_thread_info->end_cond); +} + static void wait_pending_reference(void) { IDATA stat = hysem_wait(ref_thread_info->pending_sem); @@ -123,6 +152,9 @@ /* do the real reference enqueue work */ vm_ref_enqueue_func(); + if(ref_thread_info->end_waiting_num) + notify_ref_enqueue_end(); + if(ref_thread_info->shutdown) break; } Index: vmcore/src/kernel_classes/native/java_lang_FinalizerThread.cpp =================================================================== --- vmcore/src/kernel_classes/native/java_lang_FinalizerThread.cpp (revision 527889) +++ vmcore/src/kernel_classes/native/java_lang_FinalizerThread.cpp (working copy) @@ -36,6 +36,7 @@ /* added for NATIVE FINALIZER THREAD */ #include "finalizer_thread.h" +#include "ref_enqueue_thread.h" /** * Implements getObject(..) method. @@ -116,10 +117,10 @@ JNIEXPORT void JNICALL Java_java_lang_FinalizerThread_runFinalizationInNativeFinalizerThreads (JNIEnv *, jclass) { - vm_enqueue_references(); + native_sync_enqueue_references(); // Do finalization in dedicated native finalizer threads. - vmmemory_manager_runfinalization(); + native_sync_run_finalization(); } /*