static struct eh_context * eh_context_initialize () { #if __GTHREADS static __gthread_once_t once = __GTHREAD_ONCE_INIT; /* Make sure that get_eh_context does not point to us anymore. Some systems have dummy thread routines in their libc that return a success (Solaris 2.6 for example). */ if (__gthread_once (&once, eh_threads_initialize) != 0 || get_eh_context == &eh_context_initialize) { /* Use static version of EH context. */ get_eh_context = &eh_context_static; } #else /* no __GTHREADS */ /* Use static version of EH context. */ get_eh_context = &eh_context_static; #endif /* no __GTHREADS */ return (*get_eh_context) (); }
static void fc_key_init_once (void) { static __gthread_once_t once = __GTHREAD_ONCE_INIT; if (__gthread_once (&once, fc_key_init) != 0 || use_fc_key < 0) use_fc_key = 0; }
static void init_object_mutex_once (void) { static __gthread_once_t once = __GTHREAD_ONCE_INIT; __gthread_once (&once, init_object_mutex); }
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 }