void ti_enumerate_roots(TIEnv *ti_env, hythread_iterator_t iterator) { TRACE2("ti.trace", "enumerating roots"); // FIXME: weird function table manipulations void (*save_gc_add_root_set_entry) (Managed_Object_Handle *ref, Boolean pinned); void (*save_gc_add_weak_root_set_entry) (Managed_Object_Handle *ref1, Boolean pinned, Boolean short_weak); void (*save_gc_add_root_set_entry_interior_pointer) (void **slot, int offset, Boolean pinned); void (*save_gc_add_compressed_root_set_entry) (U_32 *ref, Boolean pinned); // save away old values save_gc_add_root_set_entry = gc_add_root_set_entry; save_gc_add_weak_root_set_entry = gc_add_weak_root_set_entry; save_gc_add_root_set_entry_interior_pointer = gc_add_root_set_entry_interior_pointer; save_gc_add_compressed_root_set_entry = gc_add_compressed_root_set_entry; // hijack ti enumeration functions gc_add_root_set_entry = ti_add_root_set_entry; gc_add_weak_root_set_entry = ti_add_weak_root_set_entry; gc_add_root_set_entry_interior_pointer = ti_add_root_set_entry_interior_pointer; gc_add_compressed_root_set_entry = ti_add_compressed_root_set_entry; // Run through list of active threads and enumerate each one of them. hythread_t tm_thread = hythread_iterator_next(&iterator); while (tm_thread && !ti_env->iteration_state->abort) { vm_thread_t thread = jthread_get_vm_thread(tm_thread); if (thread) ti_enumerate_thread(ti_env, thread); tm_thread = hythread_iterator_next(&iterator); } // finally, process all the global refs ti_enumerate_globals(ti_env); // restore original enumeration functions gc_add_root_set_entry = save_gc_add_root_set_entry; gc_add_weak_root_set_entry = save_gc_add_weak_root_set_entry; gc_add_root_set_entry_interior_pointer = save_gc_add_root_set_entry_interior_pointer; gc_add_compressed_root_set_entry = save_gc_add_compressed_root_set_entry; TRACE2("ti.trace", "completed root enumeration"); }
/** * 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) { assert(threads); assert(count_ptr); hythread_group_t java_thread_group = get_java_thread_group(); assert(java_thread_group); hythread_iterator_t iterator = hythread_iterator_create(java_thread_group); IDATA count = hythread_iterator_size(iterator); IDATA java_thread_count = 0; for (IDATA i = 0; i < count; i++) { hythread_t native_thread = hythread_iterator_next(&iterator); vm_thread_t vm_thread = jthread_get_vm_thread(native_thread); if (vm_thread && vm_thread->java_thread) { java_thread_count++; } } jthread *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 (IDATA i = 0; i < count; i++) { hythread_t native_thread = hythread_iterator_next(&iterator); vm_thread_t vm_thread = jthread_get_vm_thread(native_thread); if (vm_thread && vm_thread->java_thread) { hythread_suspend_disable(); ObjectHandle thr = oh_allocate_local_handle(); assert(thr); thr->object = vm_thread->java_thread->object; assert(thr->object); hythread_suspend_enable(); java_threads[java_thread_count++] = thr; } } *threads = java_threads; *count_ptr = (jint)java_thread_count; IDATA status = hythread_iterator_release(&iterator); return status; } // jthread_get_all_threads
/** * Terminates all running threads in the given group. * * @param[in] group thread group * @see hythread_cancel */ IDATA VMCALL hythread_cancel_all(hythread_group_t group) { hythread_iterator_t iter; hythread_t next; hythread_t self = tm_self_tls; if (!group) { group = TM_DEFAULT_GROUP; } iter = hythread_iterator_create(group); while ((next = hythread_iterator_next (&iter)) != NULL) { if (next != self) { hythread_cancel(next); //since this method being used at shutdown it does not //make any sense to exit on error, but continue terminating threads } } hythread_iterator_release(&iter); 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) { assert(count_ptr); hythread_group_t java_thread_group = get_java_thread_group(); assert(java_thread_group); hythread_iterator_t iterator = hythread_iterator_create(java_thread_group); IDATA count = hythread_iterator_size(iterator); IDATA java_thread_count = 0; for (IDATA i = 0; i < count; i++) { hythread_t native_thread = hythread_iterator_next(&iterator); vm_thread_t vm_thread = jthread_get_vm_thread(native_thread); if (vm_thread) { java_thread_count++; } } *count_ptr = (jint)java_thread_count; IDATA status = hythread_iterator_release(&iterator); return status; } // jthread_get_thread_count
/** * Returns the number of blocked threads. * * @param[out] count_ptr number of threads. */ IDATA VMCALL jthread_get_blocked_count(jint * count_ptr) { assert(count_ptr); hythread_group_t java_thread_group = get_java_thread_group(); assert(java_thread_group); hythread_iterator_t iterator = hythread_iterator_create(java_thread_group); IDATA count = hythread_iterator_size(iterator); IDATA thread_count = 0; for (IDATA i = 0; i < count; i++) { hythread_t native_thread = hythread_iterator_next(&iterator); if (native_thread && hythread_is_blocked_on_monitor_enter(native_thread)) { thread_count++; } } *count_ptr = (jint)thread_count; IDATA status = hythread_iterator_release(&iterator); return status; } // jthread_get_blocked_count
ncaiError JNICALL ncaiGetAllThreads(ncaiEnv *env, jint *count_ptr, ncaiThread **threads_ptr) { TRACE2("ncai.thread", "GetAllThreads called"); SuspendEnabledChecker sec; if (env == NULL) return NCAI_ERROR_INVALID_ENVIRONMENT; if (threads_ptr == NULL || count_ptr == NULL) return NCAI_ERROR_NULL_POINTER; hythread_group_t* groups; int group_count; IDATA status; int i, res_count = 0; status = hythread_group_get_list(&groups, &group_count); if (status != TM_ERROR_NONE) return NCAI_ERROR_INTERNAL; for (i = 0; i < group_count; i++) { hythread_t cur_thread; hythread_iterator_t iterator = hythread_iterator_create(groups[i]); while (iterator && (cur_thread = hythread_iterator_next(&iterator))) { if (ncai_thread_is_alive(cur_thread)) res_count++; } hythread_iterator_release(&iterator); } ncaiThread* res_threads = (ncaiThread*)ncai_alloc(sizeof(void*)*res_count); if (res_threads == NULL) return NCAI_ERROR_OUT_OF_MEMORY; int index = 0; for (i = 0; i < group_count; i++) { hythread_t cur_thread; hythread_iterator_t iterator = hythread_iterator_create(groups[i]); while (iterator && (cur_thread = hythread_iterator_next(&iterator))) { if (index >= res_count) break; // some threads were created between two cycles if (!ncai_thread_is_alive(cur_thread)) continue; res_threads[index] = (ncaiThread)cur_thread; ++index; } hythread_iterator_release(&iterator); } *threads_ptr = res_threads; *count_ptr = index; return NCAI_ERROR_NONE; }