void __pthread_destroy_specifics() { pthread_descr self = thread_self(); int i, j, round, found_nonzero; destr_function destr; void * data; for (round = 0, found_nonzero = 1; found_nonzero && round < PTHREAD_DESTRUCTOR_ITERATIONS; round++) { found_nonzero = 0; for (i = 0; i < PTHREAD_KEY_1STLEVEL_SIZE; i++) if (THREAD_GETMEM_NC(self, p_specific[i]) != NULL) for (j = 0; j < PTHREAD_KEY_2NDLEVEL_SIZE; j++) { destr = pthread_keys[i * PTHREAD_KEY_2NDLEVEL_SIZE + j].destr; data = THREAD_GETMEM_NC(self, p_specific[i])[j]; if (destr != NULL && data != NULL) { THREAD_GETMEM_NC(self, p_specific[i])[j] = NULL; destr(data); found_nonzero = 1; } } } __pthread_lock(THREAD_GETMEM(self, p_lock), self); for (i = 0; i < PTHREAD_KEY_1STLEVEL_SIZE; i++) { if (THREAD_GETMEM_NC(self, p_specific[i]) != NULL) { free(THREAD_GETMEM_NC(self, p_specific[i])); THREAD_SETMEM_NC(self, p_specific[i], NULL); } } __pthread_unlock(THREAD_GETMEM(self, p_lock)); }
static int libc_internal_tsd_set(enum __libc_tsd_key_t key, const void * pointer) { pthread_descr self = thread_self(); THREAD_SETMEM_NC(self, p_libc_specific[key], (void *) pointer); return 0; }
int __pthread_internal_tsd_set (int key, const void * pointer) { pthread_descr self = thread_self(); THREAD_SETMEM_NC(self, p_libc_specific[key], (void *) pointer); return 0; }
int attribute_hidden __pthread_internal_tsd_set (int key, const void * pointer) { pthread_descr self = thread_self(); THREAD_SETMEM_NC(self, p_libc_specific, key, (void *) pointer); return 0; }
int __pthread_setspecific(pthread_key_t key, const void * pointer) { pthread_descr self = thread_self(); unsigned int idx1st, idx2nd; if (key >= PTHREAD_KEYS_MAX || !pthread_keys[key].in_use) return EINVAL; idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE; idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE; if (THREAD_GETMEM_NC(self, p_specific[idx1st]) == NULL) { void *newp = calloc(PTHREAD_KEY_2NDLEVEL_SIZE, sizeof (void *)); if (newp == NULL) return ENOMEM; THREAD_SETMEM_NC(self, p_specific[idx1st], newp); } THREAD_GETMEM_NC(self, p_specific[idx1st])[idx2nd] = (void *) pointer; return 0; }