static inline struct SjLj_Function_Context * _Unwind_SjLj_GetContext (void) { #if __GTHREADS if (use_fc_key < 0) fc_key_init_once (); if (use_fc_key) return __gthread_getspecific (fc_key); #endif return fc_static; }
static struct eh_context * eh_context_specific () { struct eh_context *eh; eh = (struct eh_context *) __gthread_getspecific (eh_context_key); if (! eh) { eh = new_eh_context (); if (__gthread_setspecific (eh_context_key, (void *) eh) != 0) __terminate (); } return eh; }
void _Unwind_SjLj_Register (struct SjLj_Function_Context *fc) { #if __GTHREADS if (use_fc_key < 0) fc_key_init_once (); if (use_fc_key) { fc->prev = __gthread_getspecific (fc_key); __gthread_setspecific (fc_key, fc); } else #endif { fc->prev = fc_static; fc_static = fc; } }
void * __emutls_get_address (struct __emutls_object *obj) { if (! __gthread_active_p ()) { if (__builtin_expect (obj->loc.ptr == NULL, 0)) obj->loc.ptr = emutls_alloc (obj); return obj->loc.ptr; } #ifndef __GTHREADS abort (); #else pointer offset = obj->loc.offset; if (__builtin_expect (offset == 0, 0)) { static __gthread_once_t once = __GTHREAD_ONCE_INIT; __gthread_once (&once, emutls_init); __gthread_mutex_lock (&emutls_mutex); offset = obj->loc.offset; if (offset == 0) { offset = ++emutls_size; obj->loc.offset = offset; } __gthread_mutex_unlock (&emutls_mutex); } struct __emutls_array *arr = __gthread_getspecific (emutls_key); if (__builtin_expect (arr == NULL, 0)) { pointer size = offset + 32; arr = calloc (size + 1, sizeof (void *)); if (arr == NULL) abort (); arr->size = size; __gthread_setspecific (emutls_key, (void *) arr); } else if (__builtin_expect (offset > arr->size, 0)) { pointer orig_size = arr->size; pointer size = orig_size * 2; if (offset > size) size = offset + 32; arr = realloc (arr, (size + 1) * sizeof (void *)); if (arr == NULL) abort (); arr->size = size; memset (arr->data + orig_size, 0, (size - orig_size) * sizeof (void *)); __gthread_setspecific (emutls_key, (void *) arr); } void *ret = arr->data[offset - 1]; if (__builtin_expect (ret == NULL, 0)) { ret = emutls_alloc (obj); arr->data[offset - 1] = ret; } return ret; #endif }