#include <config.h> #include <pthread.h> #include <stdio.h> #include <unistd.h> #include <time.h> #ifdef HAVE_TLS #define COUNT 10 static int race; static __thread int local; __thread int global; extern __thread int static_extern; extern __thread int so_extern; /* deliberate failure */ static int *test_race(void) { return ∽̱ } static int *test_local(void) { return &local; } static int *test_global(void) { return &global; } static int *test_static_extern(void) { return &static_extern; } static int *test_so_extern(void) { return &so_extern; } static const struct timespec awhile = { 0, 200000000 }; typedef int *(*func_t)(void); struct testcase { const char *name; func_t func; char pad[2 * (8 - sizeof(void*))]; }; static void *tls_ptr(void *p) { struct testcase *test = (struct testcase *)p; int *ip = (*test->func)(); int here = 0; int i; for(i = 0; i < COUNT; i++) { int a = (*ip)++; int b = here++; if (a != b) printf("tls_ptr: case \"%s\" has mismatch: *ip=%d here=%d\n", test->name, a, b); nanosleep(&awhile, 0); } return 0; } int *test_so_extern(void); int *test_so_local(void); int *test_so_global(void); static const struct testcase tests[] = { #define T(t) { #t, test_##t } T(race), T(local), T(global), T(static_extern), T(so_extern), T(so_local), T(so_global), #undef T }; #define NTESTS (sizeof(tests)/sizeof(*tests)) int main() { pthread_t threads[NTESTS*2]; int curthread = 0; static int i; for(i = 0; i < NTESTS; i++) { pthread_create(&threads[curthread++], NULL, tls_ptr, (void *)&tests[i]); pthread_create(&threads[curthread++], NULL, tls_ptr, (void *)&tests[i]); } for(i = 0; i < curthread; i++) pthread_join(threads[i], NULL); return 0; } #else int main() { printf("FAILED: no compiler support for __thread\n"); return 1; } #endif