/**
 * Initialize a threading library.
 * 
 * @note This must only be called once.
 * 
 * If any OS threads were created before calling this function, they must be attached using
 * hythread_attach before accessing any thread library functions. 
 * 
 * @param[in] lib pointer to the thread library to be initialized (non-NULL)
 * @return The thread library's initStatus will be set to 0 on success or 
 * a negative value on failure.
 */
void VMCALL hythread_init(hythread_library_t lib) {
    apr_status_t apr_status;
    IDATA status;
    hythread_monitor_t *mon;

    // Current implementation doesn't support more than one library instance.
    if (TM_LIBRARY == NULL) {
        TM_LIBRARY = lib;
    }
    assert(TM_LIBRARY == lib);

    if (hythread_library_state != TM_LIBRARY_STATUS_NOT_INITIALIZED)
        return;
    hythread_library_state = TM_LIBRARY_STATUS_INITIALIZED;
     
    apr_status = apr_initialize();
    assert(apr_status == APR_SUCCESS);
    // TM_POOL will be NULL if hythread_lib_create was not used to create the library
    if (TM_POOL == NULL) {
        apr_status = apr_pool_create(&TM_POOL, NULL);
        assert(apr_status == APR_SUCCESS);
    }

    apr_status = apr_threadkey_private_create(&TM_THREAD_KEY, NULL, TM_POOL);
    assert(apr_status == APR_SUCCESS);
    
    status = port_mutex_create(&lib->TM_LOCK, APR_THREAD_MUTEX_NESTED);
    assert(status == TM_ERROR_NONE);
    status = port_mutex_create(&TM_START_LOCK, APR_THREAD_MUTEX_NESTED);
    assert(status == TM_ERROR_NONE);
     
    status = init_group_list();
    assert(status == TM_ERROR_NONE);

    // Create default group - hosts any thread crated with NULL group
    status = hythread_group_create(&TM_DEFAULT_GROUP);
    assert(status == TM_ERROR_NONE);

    //nondaemon thread barrier
    ////
    lib->nondaemon_thread_count = 0;
    status = hycond_create(&lib->nondaemon_thread_cond);
    assert(status == TM_ERROR_NONE);
 
    // init global monitor
    status=hythread_monitor_init_with_name(&p_global_monitor, 0, "Thread Global Monitor");
    assert(status == TM_ERROR_NONE);

    mon = (hythread_monitor_t*)hythread_global(GLOBAL_MONITOR_NAME);
    *mon = p_global_monitor;
    assert(mon);
}
示例#2
0
/**
 * Creates new latch.
 *
 * Latch allows one or more threads to wait until a set of operations 
 * being performed in other threads are complete. Latch serves as a gate for the threads 
 * which are waiting until it is opened. Latch initialized to N counts can be used 
 * to make one thread wait until N threads have completed some action, or some
 * action has been performed N times.
 * The key difference between latch and traditional semaphore is that latch notifies 
 * every waiting threads when it reaches zero, while semaphore notifies only one waiting thread.
 *
 * @param[out] latch the memory address where the newly created latch 
 *        will be stored
 * @param[in] count the created key
 * @sa java.util.concurrent.CountDownLatch 
 */
IDATA VMCALL hylatch_create(hylatch_t *latch_ptr, IDATA count) {
    int res;
    hylatch_t latch;
    
    latch = malloc(sizeof(HyLatch));
    if (latch == NULL) {
        return TM_ERROR_OUT_OF_MEMORY;
    }
    res = port_mutex_create(&latch->mutex, APR_THREAD_MUTEX_DEFAULT);
    if (res) {
        goto cleanup;
    }
    res = hycond_create(&latch->condition);
    if (res) {
        goto cleanup_mutex;
    }
    latch->count = count;
    *latch_ptr = latch;
    return TM_ERROR_NONE;

cleanup_mutex:
    port_mutex_destroy(&latch->mutex);

cleanup:
    free(latch);
    return res;
}
示例#3
0
/**
 * Acquire and initialize a new monitor from the threading library.
 *
 * @param[out] mon_ptr pointer to a hythread_monitor_t to be set to point to the new monitor
 * @param[in] flags initial flag values for the monitor
 * @param[in] name pointer to a C string with a description of how the monitor will be used (may be NULL)<br>
 * If non-NULL, the C string must be valid for the entire life of the monitor
 *
 * @return  0 on success or negative value on failure
 *
 * @see hythread_monitor_destroy
 *
 */
IDATA VMCALL hythread_monitor_init_with_name(hythread_monitor_t *mon_ptr, UDATA flags, const char *name) {
    int r;
    hythread_monitor_t mon;

    mon = calloc(1, sizeof(HyThreadMonitor));
    if (mon == NULL) {
        return TM_ERROR_OUT_OF_MEMORY;
    }
    r = port_mutex_create(&mon->mutex, APR_THREAD_MUTEX_NESTED);
    if (r) {
        goto cleanup;
    }
    r = hycond_create(&mon->condition);
    if (r) {
        goto cleanup;
    }

    mon->flags = flags;
    mon->name  = name;

    *mon_ptr = mon;
    return TM_ERROR_NONE;

cleanup:
    free(mon);
    return r;
}
示例#4
0
int initialize_signals()
{
    apr_status_t aprerr = port_mutex_create(&g_mutex, APR_THREAD_MUTEX_NESTED);

    if (aprerr != APR_SUCCESS)
        return -1;

    BOOL ok = SetConsoleCtrlHandler((PHANDLER_ROUTINE)ctrl_handler, TRUE);

    if (!ok)
        return -1;

    // Adding vectored exception handler
    veh = AddVectoredExceptionHandler(0, vectored_exception_handler);

    if (!veh)
        return -1;

    prev_sig = signal(SIGABRT, (sigh_t)sigabrt_handler);

    if (prev_sig == SIG_ERR)
        return -1;

    disable_assert_dialogs();
    asserts_disabled = true;

    return 0;
}
static IDATA init_group_list() {
    // Initial group, does not contain any actual group, but serves 
    //as a head and a tail of this list;
    hythread_group_t dummy;

    
    //this group will exist as long as TM lives, so it's ok to have 
    //the same pool for them
    ////
    dummy = (hythread_group_t)apr_pcalloc(TM_POOL, sizeof(HyThreadGroup));
    assert(dummy);

    dummy->next = dummy->prev = dummy;
    group_list = dummy;
    groups_count = 0;

    lock_table = (HyFatLockTable *) malloc (sizeof(HyFatLockTable));
    memset(lock_table, 0, sizeof(HyFatLockTable));
    lock_table->tables[0] = (hythread_monitor_t *)calloc(HY_FAT_TABLE_ENTRIES,
                                              sizeof(hythread_monitor_t));
    lock_table->live_objs = (unsigned char *)calloc(HY_FAT_TABLE_ENTRIES,
                                         sizeof(unsigned char));
    lock_table->size = HY_FAT_TABLE_ENTRIES;
    lock_table->array_cursor = 0;

    assert (lock_table);
    assert (lock_table->tables[0]);
    assert (lock_table->live_objs);
    
    if (port_mutex_create(&lock_table->mutex, APR_THREAD_MUTEX_NESTED)) {
        return TM_ERROR_OUT_OF_MEMORY;
    }

    if (hycond_create(&lock_table->write)) {
        return TM_ERROR_OUT_OF_MEMORY;
    }

    if (hycond_create(&lock_table->read)) {
        return TM_ERROR_OUT_OF_MEMORY;
    }
    
    lock_table->readers_reading = 0;
    lock_table->readers_waiting = 0;
    lock_table->writers_waiting = 0;
    lock_table->state = HYTHREAD_LOCKTABLE_IDLE;

    return TM_ERROR_NONE;
}
示例#6
0
static IDATA jthread_init_jvmti_monitor_table()
{
    IDATA status = hythread_global_lock();
    if (status != TM_ERROR_NONE) {
        return status;
    }
    if (!jvmti_monitor_table) {
        if (array_create(&jvmti_monitor_table)) {
            hythread_global_unlock();
            return TM_ERROR_OUT_OF_MEMORY;
        }
        status = port_mutex_create(&jvmti_monitor_table_lock, APR_THREAD_MUTEX_NESTED);
        if (status != TM_ERROR_NONE) {
            hythread_global_unlock();
            return status;
        }
    }
    status = hythread_global_unlock();
    return status;
} // jthread_init_jvmti_monitor_table
示例#7
0
EBProfileCollector::EBProfileCollector(EM_PC_Interface* em, const std::string& name, JIT_Handle genJit, 
                                       EB_ProfilerMode _mode, U_32 _eThreshold, U_32 _bThreshold,
                                       U_32 _initialTimeout, U_32 _timeout) 
                                       : ProfileCollector(em, name, EM_PCTYPE_ENTRY_BACKEDGE, genJit),
                                        mode(_mode), eThreshold(_eThreshold), bThreshold(_bThreshold), 
                                        initialTimeout(_initialTimeout), timeout(_timeout), loggingEnabled(false)
                                       
{
    assert( (mode == EB_PCMODE_SYNC ? (initialTimeout==0 && timeout==0) : timeout > 0) );
    catName = std::string(LOG_DOMAIN) + ".profiler." + name;
    loggingEnabled =  log_is_info_enabled(LOG_DOMAIN);
    if (!loggingEnabled) {
        loggingEnabled = log_is_info_enabled(catName.c_str());
    }
    if (loggingEnabled) {
        std::ostringstream msg;
        msg<< "EM: entry-backedge profiler intialized: "<<name
            <<" entry threshold:"<<eThreshold << " backedge threshold:"<<bThreshold
            <<" mode:"<<(mode == EB_PCMODE_ASYNC? "ASYNC": "SYNC");
        INFO2(catName.c_str(), msg.str().c_str());
    }

    port_mutex_create(&profilesLock, APR_THREAD_MUTEX_NESTED);
}
示例#8
0
/**
 * Initializes a new thread structure.
 */
IDATA VMCALL hythread_struct_init(hythread_t new_thread) 
{
    char jstatus;
    IDATA status;

    assert(new_thread);
    jstatus = new_thread->java_status;
    if (!new_thread->os_handle) {
        // new thread, create thread primitives
        memset(new_thread, 0, sizeof(HyThread));
        status = hysem_create(&new_thread->resume_event, 0, 1);
        assert(status == TM_ERROR_NONE);
        status = port_mutex_create(&new_thread->mutex, APR_THREAD_MUTEX_NESTED);
        assert(status == TM_ERROR_NONE);
        status = hythread_monitor_init(&new_thread->monitor, 0);
        assert(status == TM_ERROR_NONE);
    } else {
        // old thread, reset structure
        int result;
        hysem_t resume;
        osmutex_t mutex;
        hythread_monitor_t monitor;

        // release thread OS handle
        result = port_thread_free_handle(new_thread->os_handle);
        assert(0 == result);

        resume = new_thread->resume_event;
        mutex = new_thread->mutex;
        monitor = new_thread->monitor;

        // zero new thread
        memset(new_thread, 0, sizeof(HyThread));

        new_thread->resume_event = resume;
        new_thread->mutex = mutex;
        new_thread->monitor = monitor;
    }
    assert(new_thread->os_handle == 0);

    new_thread->java_status = jstatus;
    new_thread->priority   = HYTHREAD_PRIORITY_NORMAL;


#ifdef ORDER
    new_thread->alloc_count = 0;
    new_thread->thread_create_count = 0;
    new_thread->p_tid = 0;
    new_thread->p_count = 0;
//    new_thread->isInVMRegistry = 0;
#endif


    port_mutex_lock(&new_thread->mutex);
    new_thread->state = TM_THREAD_STATE_NEW;
    port_mutex_unlock(&new_thread->mutex);

    status = hysem_set(new_thread->resume_event, 0);
    assert(status == TM_ERROR_NONE);

    return TM_ERROR_NONE;
}
示例#9
0
/**
 * Creates and initializes condition variable.
 *
 * @param[in] cond the address of the condition variable.
 * @return 0 on success, non-zero otherwise.
 */
IDATA VMCALL hycond_create (hycond_t *cond) {
    cond->dummy_node.next = cond->dummy_node.prev = &cond->dummy_node;
    port_mutex_create(&cond->queue_mutex, APR_THREAD_MUTEX_NESTED);
    return 0;
}