Index: gc_gen/src/thread/mutator.cpp =================================================================== --- gc_gen/src/thread/mutator.cpp (revision 561621) +++ gc_gen/src/thread/mutator.cpp (working copy) @@ -52,11 +52,10 @@ mutator->next = (Mutator *)gc->mutator_list; gc->mutator_list = mutator; + gc->num_mutators++; unlock(gc->mutator_list_lock); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - gc->num_mutators++; - gc_set_tls(mutator); return; @@ -73,16 +72,6 @@ allocactor_destruct_local_chunks((Allocator*)mutator); #endif - if(gc_is_gen_mode()){ /* put back the remset when a mutator exits */ - pool_put_entry(gc->metadata->mutator_remset_pool, mutator->rem_set); - mutator->rem_set = NULL; - } - - if(mutator->obj_with_fin){ - pool_put_entry(gc->finref_metadata->obj_with_fin_pool, mutator->obj_with_fin); - mutator->obj_with_fin = NULL; - } - lock(gc->mutator_list_lock); // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv volatile Mutator *temp = gc->mutator_list; @@ -95,11 +84,20 @@ } temp->next = mutator->next; } + gc->num_mutators--; unlock(gc->mutator_list_lock); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - - gc->num_mutators--; + if(gc_is_gen_mode()){ /* put back the remset when a mutator exits */ + pool_put_entry(gc->metadata->mutator_remset_pool, mutator->rem_set); + mutator->rem_set = NULL; + } + + if(mutator->obj_with_fin){ + pool_put_entry(gc->finref_metadata->obj_with_fin_pool, mutator->obj_with_fin); + mutator->obj_with_fin = NULL; + } + //gc_set_tls(NULL); return; Index: vmcore/include/finalizer_thread.h =================================================================== --- vmcore/include/finalizer_thread.h (revision 561621) +++ vmcore/include/finalizer_thread.h (working copy) @@ -43,17 +43,19 @@ typedef struct Fin_Thread_Info { - hysem_t pending_sem; // finalizer pending event + hysem_t pending_sem; // finalizer pending event + hysem_t attached_sem; // fin thread attached event - hycond_t end_cond; // finalization end condition variable - hymutex_t end_mutex; // finalization end mutex + /* Using pair of cond and mutex rather than sem is because the waiting thread num is not constant */ + hycond_t end_cond; // finalization end condition variable + hymutex_t end_mutex; // finalization end mutex - hycond_t mutator_block_cond; // mutator block condition variable for heavy finalizable obj load - hymutex_t mutator_block_mutex; // mutator block mutex for heavy finalizable obj load + /* Using pair of cond and mutex rather than sem is because the waiting thread num is not constant */ + hycond_t mutator_block_cond; // mutator block condition variable for heavy finalizable obj load + hymutex_t mutator_block_mutex; // mutator block mutex for heavy finalizable obj load hythread_t *thread_ids; volatile unsigned int thread_num; - volatile unsigned int thread_attached; volatile Boolean shutdown; volatile Boolean on_exit; Index: vmcore/include/ref_enqueue_thread.h =================================================================== --- vmcore/include/ref_enqueue_thread.h (revision 561621) +++ vmcore/include/ref_enqueue_thread.h (working copy) @@ -33,11 +33,15 @@ typedef struct Ref_Enqueue_Thread_Info { - hysem_t pending_sem; + hysem_t pending_sem; // weakref pending event + hysem_t attached_sem; // ref enqueue thread attached event + + /* Using pair of cond and mutex rather than sem is because the waiting thread num is not constant */ 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 thread_num; volatile unsigned int end_waiting_num; // thread num waiting for finalization end }Ref_Enqueue_Thread_Info; Index: vmcore/src/init/finalizer_thread.cpp =================================================================== --- vmcore/src/init/finalizer_thread.cpp (revision 561621) +++ vmcore/src/init/finalizer_thread.cpp (working copy) @@ -63,25 +63,7 @@ return 0; } -static IDATA finalizer_thread_func(void **args); - -static void set_fin_thread_attached(void) -{ fin_thread_info->thread_attached = 1; } - -static void dec_fin_thread_num(void) -{ atomic_dec32(&fin_thread_info->thread_num); } - -static volatile unsigned int get_fin_thread_attached(void) -{ return fin_thread_info->thread_attached; } - -static void clear_fin_thread_attached(void) -{ fin_thread_info->thread_attached = 0; } - -static void wait_fin_thread_attached(void) -{ while(!fin_thread_info->thread_attached){hythread_yield();}} - - -jobject get_system_thread_group(JNIEnv* jni_env) +jobject get_system_thread_group(JNIEnv *jni_env) { jclass thread_class = GetObjectClass(jni_env, jthread_self()); jfieldID sysTG_field = GetStaticFieldID(jni_env, thread_class, @@ -90,8 +72,11 @@ return GetStaticObjectField(jni_env, thread_class, sysTG_field); } -void finalizer_threads_init(JavaVM *java_vm, JNIEnv* jni_env) -{ if(!native_fin_thread_flag) +static IDATA finalizer_thread_func(void **args); + +void finalizer_threads_init(JavaVM *java_vm, JNIEnv *jni_env) +{ + if(!native_fin_thread_flag) return; fin_thread_info = (Fin_Thread_Info *)STD_MALLOC(sizeof(Fin_Thread_Info)); @@ -105,6 +90,9 @@ IDATA status = hysem_create(&fin_thread_info->pending_sem, 0, fin_thread_info->thread_num); assert(status == TM_ERROR_NONE); + status = hysem_create(&fin_thread_info->attached_sem, 0, fin_thread_info->thread_num); + assert(status == TM_ERROR_NONE); + status = hycond_create(&fin_thread_info->end_cond); assert(status == TM_ERROR_NONE); status = hymutex_create(&fin_thread_info->end_mutex, TM_MUTEX_DEFAULT); @@ -118,15 +106,13 @@ fin_thread_info->thread_ids = (hythread_t *)STD_MALLOC(sizeof(hythread_t) * fin_thread_info->thread_num); for(unsigned int i = 0; i < fin_thread_info->thread_num; i++){ - void **args = (void **)STD_MALLOC(sizeof(void *) * 3); - args[0] = (void *)java_vm; - args[1] = (void *)(UDATA)(i + 1); - args[2] = (void*)get_system_thread_group(jni_env); + void **args = (void **)STD_MALLOC(sizeof(void *) * 2); + args[0] = (void*)java_vm; + args[1] = (void*)get_system_thread_group(jni_env); fin_thread_info->thread_ids[i] = NULL; - clear_fin_thread_attached(); status = hythread_create(&fin_thread_info->thread_ids[i], 0, FINALIZER_THREAD_PRIORITY, 0, (hythread_entrypoint_t)finalizer_thread_func, args); assert(status == TM_ERROR_NONE); - wait_fin_thread_attached(); + hysem_wait(fin_thread_info->attached_sem); } } @@ -179,6 +165,7 @@ atomic_dec32(&fin_thread_info->end_waiting_num); unsigned int temp = vm_get_finalizable_objects_quantity(); if(must_wait){ + /* The second condition stands for that as long as there are objects finalized the current thread will continue waiting */ if((status != TM_ERROR_NONE) && (fin_obj_num == temp)) break; }else{ if(status != TM_ERROR_NONE) break; @@ -216,24 +203,22 @@ JavaVM *java_vm = (JavaVM *)args[0]; JNIEnv *jni_env; char *name = "finalizer"; - // FIXME: use args[1] (thread number) to distinguish finalization threads by name JavaVMAttachArgs *jni_args = (JavaVMAttachArgs*)STD_MALLOC(sizeof(JavaVMAttachArgs)); jni_args->version = JNI_VERSION_1_2; jni_args->name = name; - jni_args->group = (jobject)args[2]; + jni_args->group = (jobject)args[1]; IDATA status = AttachCurrentThreadAsDaemon(java_vm, (void**)&jni_env, jni_args); assert(status == JNI_OK); set_current_thread_context_loader(jni_env); - assert(!get_fin_thread_attached()); - set_fin_thread_attached(); + hysem_post(fin_thread_info->attached_sem); /* Choice: use VM_thread or hythread to indicate the finalizer thread ? * Now we use hythread * p_TLS_vmthread->finalize_thread_flags = thread_id; */ - while(true){ + while(TRUE){ /* Waiting for pending finalizers */ wait_pending_finalizer(); @@ -254,8 +239,7 @@ vm_heavy_finalizer_resume_mutator(); status = DetachCurrentThread(java_vm); assert(status == JNI_OK); - dec_fin_thread_num(); - //status = jthread_detach(java_thread); + atomic_dec32(&fin_thread_info->thread_num); return status; } @@ -279,7 +263,7 @@ void vm_heavy_finalizer_block_mutator(void) { - /* Maybe self test is not needed. This needs further test. */ + /* Finalizer thread shouldn't block itself. Maybe self test is not needed. This needs further test. */ if(self_is_finalizer_thread()) return; @@ -297,11 +281,3 @@ if(gc_clear_mutator_block_flag()) hycond_notify_all(&fin_thread_info->mutator_block_cond); } - - - - - - - - Index: vmcore/src/init/ref_enqueue_thread.cpp =================================================================== --- vmcore/src/init/ref_enqueue_thread.cpp (revision 561621) +++ vmcore/src/init/ref_enqueue_thread.cpp (working copy) @@ -38,9 +38,8 @@ { native_ref_thread_flag = flag; } +extern jobject get_system_thread_group(JNIEnv *jni_env); static IDATA ref_enqueue_thread_func(void **args); -static void wait_ref_thread_attached(void); -extern jobject get_system_thread_group(JNIEnv* jni_env); void ref_enqueue_thread_init(JavaVM *java_vm, JNIEnv* jni_env) { @@ -49,23 +48,27 @@ ref_thread_info = (Ref_Enqueue_Thread_Info *)STD_MALLOC(sizeof(Ref_Enqueue_Thread_Info)); ref_thread_info->shutdown = false; - ref_thread_info->thread_attached = 0; IDATA status = hysem_create(&ref_thread_info->pending_sem, 0, REF_ENQUEUE_THREAD_NUM); assert(status == TM_ERROR_NONE); + status = hysem_create(&ref_thread_info->attached_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); + ref_thread_info->thread_num = REF_ENQUEUE_THREAD_NUM; + void **args = (void **)STD_MALLOC(sizeof(void *)*2); args[0] = (void *)java_vm; args[1] = (void*)get_system_thread_group(jni_env); status = hythread_create(NULL, 0, REF_ENQUEUE_THREAD_PRIORITY, 0, (hythread_entrypoint_t)ref_enqueue_thread_func, args); assert(status == TM_ERROR_NONE); - wait_ref_thread_attached(); + hysem_wait(ref_thread_info->attached_sem); } void ref_enqueue_shutdown(void) @@ -80,17 +83,17 @@ static uint32 atomic_dec32(volatile apr_uint32_t *mem) { return (uint32)apr_atomic_dec32(mem); } -static void inc_ref_thread_num(void) -{ atomic_inc32(&ref_thread_info->thread_attached); } - -static void dec_ref_thread_num(void) -{ atomic_dec32(&ref_thread_info->thread_attached); } - -static void wait_ref_thread_attached(void) -{ while(ref_thread_info->thread_attached < REF_ENQUEUE_THREAD_NUM); } - void wait_native_ref_thread_detached(void) -{ while(ref_thread_info->thread_attached){hythread_yield();} } +{ + hymutex_lock(&ref_thread_info->end_mutex); + while(ref_thread_info->thread_num){ + 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)1000, 0); + atomic_dec32(&ref_thread_info->end_waiting_num); + if(status != TM_ERROR_NONE) break; + } + hymutex_unlock(&ref_thread_info->end_mutex); +} static void wait_ref_enqueue_end(void) { @@ -109,7 +112,7 @@ void activate_ref_enqueue_thread(Boolean wait) { - IDATA stat = hysem_set(ref_thread_info->pending_sem, REF_ENQUEUE_THREAD_NUM); + IDATA stat = hysem_set(ref_thread_info->pending_sem, ref_thread_info->thread_num); assert(stat == TM_ERROR_NONE); if(wait) @@ -143,9 +146,9 @@ IDATA status = AttachCurrentThreadAsDaemon(java_vm, (void**)&jni_env, jni_args); assert(status == JNI_OK); set_current_thread_context_loader(jni_env); - inc_ref_thread_num(); + hysem_post(ref_thread_info->attached_sem); - while(true){ + while(TRUE){ /* Waiting for pending weak references */ wait_pending_reference(); @@ -160,7 +163,6 @@ } status = DetachCurrentThread(java_vm); - dec_ref_thread_num(); - //status = jthread_detach(java_thread); + atomic_dec32(&ref_thread_info->thread_num); return status; }