Beispiel #1
0
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");
}
Beispiel #2
0
/**
 * 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
Beispiel #3
0
/** 
 * 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;
}
Beispiel #4
0
/**
 * 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
Beispiel #5
0
/**
 * 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
Beispiel #6
0
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;
}