/** * This DLL is being unloaded, do any clean up required. * This may be called more than once!! */ JNIEXPORT void JNICALL JNI_OnUnload (JavaVM * vm, void *reserved) { JNIEnv *env; void *keyInitCountPtr = GLOBAL_DATA (keyInitCount); void **jclIdCache = GLOBAL_DATA (JCL_ID_CACHE); if ((*vm)->GetEnv (vm, (void **) &env, JNI_VERSION_1_2) == JNI_OK) { JniIDCache *idCache = (JniIDCache *) HY_VMLS_GET (env, *jclIdCache); if (idCache) { JCLZipFileLink *zipfileHandles; JCLZipFile *jclZipFile; PORT_ACCESS_FROM_ENV (env); #ifdef HY_ZIP_API VMI_ACCESS_FROM_ENV(env); VMIZipFunctionTable *zipFuncs = (*VMI)->GetZipFunctions(VMI); #endif /* HY_ZIP_API */ /* Detach from the common library */ ClearLibDetach (env); /* Close and free the HyZipFile handles */ zipfileHandles = JCL_CACHE_GET (env, zipfile_handles); if (zipfileHandles != NULL) { jclZipFile = zipfileHandles->next; while (jclZipFile != NULL) { JCLZipFile *next = jclZipFile->next; #ifndef HY_ZIP_API zip_closeZipFile (PORTLIB, &jclZipFile->hyZipFile); #else /* HY_ZIP_API */ zipFuncs->zip_closeZipFile (VMI, &jclZipFile->hyZipFile); #endif /* HY_ZIP_API */ jclmem_free_memory (env, jclZipFile); jclZipFile = next; } MUTEX_DESTROY (zipfileHandles->mutex); jclmem_free_memory (env, zipfileHandles); } /* Free any global references */ freeReferences (env); /* Free VMLS keys */ idCache = (JniIDCache *) HY_VMLS_GET (env, *jclIdCache); HY_VMLS_FNTBL (env)->HYVMLSFreeKeys (env, keyInitCountPtr, jclIdCache, NULL); hymem_free_memory (idCache); } } }
void call_omrthread_init(void) { omrthread_library_t lib = GLOBAL_DATA(default_library); #if defined(LINUX) || !defined(J9_PRIORITY_MAP) || defined(J9OS_I5) || defined(OSX) if (initialize_priority_map()) { goto thread_init_error; } #endif /* defined(LINUX) || !defined(J9_PRIORITY_MAP) || defined(J9OS_I5) || defined(OSX) */ #ifdef J9ZOS390 zos_init_yielding(); #endif #if J9THREAD_USE_MONOTONIC_COND_CLOCK initCondAttr(); /* ignore the result */ #endif omrthread_init(lib); return; thread_init_error: lib->initStatus = -1; }
intptr_t init_thread_library(void) { omrthread_library_t lib = GLOBAL_DATA(default_library); pthread_once(&init_once, call_omrthread_init); return lib->initStatus != 1; }
/** * @param[in] J9OSCond The cond to destroy * @return 0 on success */ intptr_t j9OSCond_freeAndDestroy(J9OSCond cond) { omrthread_library_t lib = GLOBAL_DATA(default_library); intptr_t rc = pthread_cond_destroy(cond); omrthread_free_memory(lib, cond); return rc; }
/** * @param[in] J9OSMutex The mutex to free * @return 0 on success */ intptr_t j9OSMutex_freeAndDestroy(J9OSMutex mutex) { omrthread_library_t lib = GLOBAL_DATA(default_library); intptr_t rc = pthread_mutex_destroy(mutex); omrthread_free_memory(lib, mutex); return rc; }
/** * @param[out] J9OSMutex* The mutex to init * @return 1 on success, 0 otherwise */ intptr_t j9OSMutex_allocAndInit(J9OSMutex *mutex) { omrthread_library_t lib = GLOBAL_DATA(default_library); intptr_t rc = 1; *mutex = (J9OSMutex)omrthread_allocate_memory(lib, sizeof(**mutex), OMRMEM_CATEGORY_OSMUTEXES); rc = (NULL != *mutex) && (pthread_mutex_init(*mutex, NULL) == 0); return rc; }
/* * Return the default threading library. * * @return pointer to the default threading library * */ static hythread_library_t get_default_library (void) { #if defined(HYVM_OUT_OF_PROCESS) return dbgGetThreadLibrary (); #else return GLOBAL_DATA (default_library); #endif }
/** * This DLL is being loaded, do any initialization required. * This may be called more than once. */ JNIEXPORT jint JNICALL JNI_OnLoad (JavaVM * vm, void *reserved) { JniIDCache *idCache; JNIEnv *env; void *keyInitCountPtr = GLOBAL_DATA (keyInitCount); void **jclIdCache = GLOBAL_DATA (JCL_ID_CACHE); if ((*vm)->GetEnv (vm, (void **) &env, JNI_VERSION_1_2) == JNI_OK) { PORT_ACCESS_FROM_ENV (env); if (HY_VMLS_FNTBL (env)-> HYVMLSAllocKeys (env, keyInitCountPtr, jclIdCache, NULL)) { goto fail; } /* This allocate must actually be done by hymem_allocate_memory. */ idCache = (JniIDCache *) hymem_allocate_memory (sizeof (JniIDCache)); if (!idCache) goto fail2; memset (idCache, 0, sizeof (JniIDCache)); HY_VMLS_SET (env, *jclIdCache, idCache); /* Attach to the common library */ if (JNI_OK != ClearLibAttach (env)) { goto fail2; } return JNI_VERSION_1_2; } fail2: HY_VMLS_FNTBL (env)->HYVMLSFreeKeys (env, keyInitCountPtr, jclIdCache, NULL); fail: return 0; }
/** * @param[in] J9OSCond* The cond to init * @return 1 on success and 0 otherwise */ intptr_t j9OSCond_allocAndInit(J9OSCond *cond) { omrthread_library_t lib = GLOBAL_DATA(default_library); intptr_t rc = 1; *cond = (J9OSCond)omrthread_allocate_memory(lib, sizeof(**cond), OMRMEM_CATEGORY_OSCONDVARS); #if J9THREAD_USE_MONOTONIC_COND_CLOCK rc = (NULL != *cond) && (pthread_cond_init(*cond, defaultCondAttr) == 0); #else rc = (NULL != *cond) && (pthread_cond_init(*cond, NULL) == 0); #endif return rc; }
/** * Perform OS-specific initializations for the threading library. * * @return 0 on success or non-zero value on failure. */ intptr_t init_thread_library(void) { omrthread_library_t lib = GLOBAL_DATA(default_library); if (lib->initStatus == 0) { HANDLE mutex = CreateMutex(NULL, TRUE, "omrthread_init_mutex"); if (mutex == NULL) { return -1; } if (lib->initStatus == 0) { omrthread_init(lib); if (lib->initStatus == 1) { atexit(omrthread_shutdown_library); } } ReleaseMutex(mutex); CloseHandle(mutex); } return lib->initStatus != 1; }
/** * Allocate a thread local storage (TLS) key. * * Create and return a new, unique key for thread local storage. * * @note The handle returned will be > 0, so it is safe to test the handle against 0 to see if it's been * allocated yet. * * @param[out] handle pointer to a key to be initialized with a key value * @param[in] finalizer a finalizer function which will be invoked when a thread is detached or terminates if the thread's TLS entry for this key is non-NULL * @return 0 on success or negative value if a key could not be allocated (i.e. all TLS has been allocated) * * @see omrthread_tls_free, omrthread_tls_set */ intptr_t omrthread_tls_alloc_with_finalizer(omrthread_tls_key_t *handle, omrthread_tls_finalizer_t finalizer) { intptr_t index; omrthread_library_t lib = GLOBAL_DATA(default_library); ASSERT(lib); *handle = 0; J9OSMUTEX_ENTER(lib->tls_mutex); for (index = 0; index < J9THREAD_MAX_TLS_KEYS; index++) { if (lib->tls_finalizers[index] == NULL) { *handle = index + 1; lib->tls_finalizers[index] = finalizer; break; } } J9OSMUTEX_EXIT(lib->tls_mutex); return index < J9THREAD_MAX_TLS_KEYS ? 0 : -1; }
/** * Release a TLS key. * * Release a TLS key previously allocated by omrthread_tls_alloc. * * @param[in] key TLS key to be freed * @return 0 on success or negative value on failure * * @see omrthread_tls_alloc, omrthread_tls_set * */ intptr_t omrthread_tls_free(omrthread_tls_key_t key) { J9PoolState state; omrthread_t each; omrthread_library_t lib = GLOBAL_DATA(default_library); ASSERT(lib); /* clear the TLS in every existing thread */ GLOBAL_LOCK_SIMPLE(lib); each = pool_startDo(lib->thread_pool, &state); while (each) { each->tls[key - 1] = NULL; each = pool_nextDo(&state); } GLOBAL_UNLOCK_SIMPLE(lib); /* now return the key to the free set */ J9OSMUTEX_ENTER(lib->tls_mutex); lib->tls_finalizers[key - 1] = NULL; J9OSMUTEX_EXIT(lib->tls_mutex); return 0; }
/** * Enable or disable monitoring of stack usage. * * @param[in] enable 0 to disable or non-zero to enable. * @return none * */ void VMCALL hythread_enable_stack_usage (UDATA enable) { hythread_library_t lib = GLOBAL_DATA (default_library); lib->stack_usage = enable; }