static thread_storage* get_thread_storage(JNIEnv* env) { thread_storage* tls = (thread_storage *)TLS_GET(tls_thread_data_key); if (tls == NULL) { tls = (thread_storage*)malloc(sizeof(thread_storage)); if (!tls) { throwByName(env, EOutOfMemory, "JNA: Can't allocate thread storage"); } else { snprintf(tls->name, sizeof(tls->name), "<uninitialized thread name>"); tls->jvm_thread = JNI_TRUE; tls->last_error = 0; tls->termination_flag = NULL; if ((*env)->GetJavaVM(env, &tls->jvm) != JNI_OK) { free(tls); throwByName(env, EIllegalState, "JNA: Could not get JavaVM"); tls = NULL; } else if (!TLS_SET(tls_thread_data_key, tls)) { free(tls); throwByName(env, EOutOfMemory, "JNA: Internal TLS error"); tls = NULL; } } } return tls; }
void INTERNAL hazardous_ptr(unsigned int which, void *ptr) {/*{{{*/ uintptr_t *hzptrs = TLS_GET(ts_hazard_ptrs); if (hzptrs == NULL) { { qthread_worker_t *wkr = qthread_internal_getworker(); if (wkr == NULL) { hzptrs = calloc(sizeof(uintptr_t), HAZARD_PTRS_PER_SHEP + 1); assert(hzptrs); do { hzptrs[HAZARD_PTRS_PER_SHEP] = (uintptr_t)QTHREAD_CASLOCK_READ(hzptr_list); } while (QT_CAS(hzptr_list, hzptrs[HAZARD_PTRS_PER_SHEP], hzptrs) != (void *)hzptrs[HAZARD_PTRS_PER_SHEP]); (void)qthread_incr(&hzptr_list_len, 1); } else { hzptrs = wkr->hazard_ptrs; } } TLS_SET(ts_hazard_ptrs, hzptrs); } assert(hzptrs); assert(which < HAZARD_PTRS_PER_SHEP); hzptrs[which] = (uintptr_t)ptr; }/*}}}*/
static QINLINE qthread_worker_id_t qt_threadqueue_worker_id(void) { qthread_worker_id_t id; qthread_worker_t *worker = (qthread_worker_t *)TLS_GET(shepherd_structs); if (worker == NULL) { return(qlib->nworkerspershep); } id = worker->worker_id; assert(id >= 0 && id < qlib->nworkerspershep); return(id); }
qthread_worker_id_t API_FUNC qthread_worker_unique(qthread_shepherd_id_t *shepherd_id) { /*{{{ */ assert(qthread_library_initialized); qthread_worker_t *worker = (qthread_worker_t *)TLS_GET(shepherd_structs); if((shepherd_id != NULL) && (worker != NULL)) { *shepherd_id = worker->shepherd->shepherd_id; } return worker ? (worker->unique_id) : NO_WORKER; } /*}}} */
void INTERNAL hazardous_release_node(void (*freefunc)(void *), void *ptr) {/*{{{*/ hazard_freelist_t *hfl = &(qthread_internal_getworker()->hazard_free_list); uintptr_t *hzptrs = TLS_GET(ts_hazard_ptrs); assert(ptr != NULL); assert(freefunc != NULL); assert(hfl->count < freelist_max); hfl->freelist[hfl->count].freefunc = freefunc; hfl->freelist[hfl->count].ptr = ptr; hfl->count++; if (hzptrs != NULL) { memset(hzptrs, 0, sizeof(uintptr_t) * HAZARD_PTRS_PER_SHEP); } if (hfl->count == freelist_max) { hazardous_scan(hfl); } }/*}}}*/
SEE ALSO Forbid(), Disable(), Enable(), Wait() INTERNALS If you want to preserve all the registers, replace this function in your $(KERNEL) directory. Otherwise this function is satisfactory. HISTORY ******************************************************************************/ #undef Exec { AROS_LIBFUNC_INIT void *KernelBase = TLS_GET(KernelBase); /* Task switches are allowed again, if a switch is pending, we should allow it. */ AROS_ATOMIC_DEC(SysBase->TDNestCnt); if( ( SysBase->TDNestCnt < 0 ) && ( SysBase->IDNestCnt < 0 ) && ( SysBase->AttnResched & 0x80 ) ) { /* Haha, you re-enabled multitasking, only to have the rug pulled out from under you feet :)