/** * 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); }
/** * 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; }
/** * 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; }
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; }
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
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); }
/** * 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; }
/** * 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; }