static void test_tss (void) { thrd_t threads[TEST_TSS_N_THREADS]; int* value = (int*)malloc(sizeof(int)); int i; *value = rand(); tss_create(&(test_tss_data.key), test_tss_free); mtx_init(&(test_tss_data.mutex), mtx_plain); test_tss_data.values_freed = 0; assert(tss_get(test_tss_data.key) == NULL); tss_set(test_tss_data.key, value); assert(tss_get(test_tss_data.key) == value); for (i = 0; i < TEST_TSS_N_THREADS; i++) { thrd_create(&(threads[i]), test_tss_thread_func, NULL); } for (i = 0; i < TEST_TSS_N_THREADS; i++) { thrd_join(threads[i], NULL); } assert(test_tss_data.values_freed == TEST_TSS_N_THREADS); assert(tss_get(test_tss_data.key) == value); tss_delete(test_tss_data.key); assert(tss_get(test_tss_data.key) == NULL); assert(test_tss_data.values_freed == TEST_TSS_N_THREADS); free(value); }
int main( void ) { #ifndef REGTEST TESTCASE(tss_create(&key, NULL) == thrd_success); TESTCASE(tss_get(key) == NULL); TESTCASE(tss_set(key, &v) == thrd_success); TESTCASE(tss_get(key) == &v); tss_delete(key); #endif return TEST_RESULTS; }
static int do_test (void) { /* Setting an invalid key should return an error. */ if (tss_set (key, TSS_VALUE) == thrd_success) FAIL_EXIT1 ("tss_set succeed where it should have failed"); if (tss_create (&key, NULL) != thrd_success) FAIL_EXIT1 ("tss_create failed"); thrd_t id; if (thrd_create (&id, tss_thrd, NULL) != thrd_success) FAIL_EXIT1 ("thrd_create failed"); if (thrd_join (id, NULL) != thrd_success) FAIL_EXIT1 ("thrd failed"); /* The value set in tss_thrd should not be visible here. */ void *value = tss_get (key); if (value != 0) FAIL_EXIT1 ("tss_get succeed where it should have failed"); tss_delete (key); return 0; }
static inline _EGLThreadInfo *_eglGetTSD(void) { #ifdef GLX_USE_TLS return (_EGLThreadInfo *) _egl_TLS; #else return (_EGLThreadInfo *) tss_get(_egl_TSD); #endif }
static int test_tss_thread_func (void* data) { int* value = (int*)malloc(sizeof(int)); (void)data; *value = rand(); assert(tss_get(test_tss_data.key) == NULL); tss_set(test_tss_data.key, value); assert(tss_get(test_tss_data.key) == value); tss_set(test_tss_data.key, NULL); assert(tss_get(test_tss_data.key) == NULL); tss_set(test_tss_data.key, value); assert(tss_get(test_tss_data.key) == value); return 0; }
static void impl_tss_dtor_invoke() { int i; for (i = 0; i < EMULATED_THREADS_TSS_DTOR_SLOTNUM; i++) { if (impl_tss_dtor_tbl[i].dtor) { void* val = tss_get(impl_tss_dtor_tbl[i].key); if (val) (impl_tss_dtor_tbl[i].dtor)(val); } } }
static int tss_thrd (void *arg) { if (tss_create (&key, NULL) != thrd_success) FAIL_EXIT1 ("tss_create failed"); if (tss_set (key, TSS_VALUE)) FAIL_EXIT1 ("tss_set failed"); void *value = tss_get (key); if (value == 0) FAIL_EXIT1 ("tss_get failed"); if (value != TSS_VALUE) FAIL_EXIT1 ("tss_get returned %p, expected %p", value, TSS_VALUE); thrd_exit (thrd_success); }
HEBI_PURE HEBI_WARNUNUSED static void * ctxgetorcreate(hebi_errhandler handler, void *arg) { struct hebi_error err; void *ctx; #if defined USE_C11_THREADS call_once(&ctxonce, &ctxkeyinit); if (UNLIKELY(!ctxkeyactive)) ctxraise(handler, arg, &ctxkeyerr); ctx = tss_get(ctxkey); #elif defined USE_POSIX_THREADS int e; e = pthread_once(&ctxonce, &ctxkeyinit); if (UNLIKELY(e)) { err.he_domain = HEBI_ERRDOM_ERRNO; err.he_code = e; ctxraise(handler, arg, &err); } if (UNLIKELY(!ctxkeyactive)) ctxraise(handler, arg, &ctxkeyerr); ctx = pthread_getspecific(ctxkey); #endif if (UNLIKELY(!ctx)) { ctx = ctxinit(&err); if (UNLIKELY(!ctx)) ctxraise(handler, arg, &err); } return ctx; }