1b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj#include <config.h> 247735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge#include <pthread.h> 347735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge#include <stdio.h> 447735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge#include <unistd.h> 547735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge#include <time.h> 647735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 7b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj#ifdef HAVE_TLS 8b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj 947735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge#define COUNT 10 1047735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 1147735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardingestatic int race; 1247735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardingestatic __thread int local; 1347735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge__thread int global; 1447735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardingeextern __thread int static_extern; 1547735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardingeextern __thread int so_extern; 1647735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 1747735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge/* deliberate failure */ 1847735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardingestatic int *test_race(void) 1947735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge{ 2047735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge return ∽̱ 2147735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge} 2247735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 2347735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardingestatic int *test_local(void) 2447735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge{ 2547735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge return &local; 2647735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge} 2747735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 2847735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardingestatic int *test_global(void) 2947735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge{ 3047735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge return &global; 3147735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge} 3247735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 3347735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardingestatic int *test_static_extern(void) 3447735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge{ 3547735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge return &static_extern; 3647735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge} 3747735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 3847735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardingestatic int *test_so_extern(void) 3947735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge{ 4047735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge return &so_extern; 4147735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge} 4247735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 43bcc95cfa30412ef9afa11005e365db3b043c9f6bflorianstatic const struct timespec awhile = { 0, 200000000 }; 4447735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 4547735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardingetypedef int *(*func_t)(void); 4647735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardingestruct testcase { 4747735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge const char *name; 4847735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge func_t func; 491670b05a4a415dbfd75b1a120713b4a206bb719ephilippe char pad[2 * (8 - sizeof(void*))]; 5047735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge}; 5147735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardingestatic void *tls_ptr(void *p) 5247735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge{ 5347735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge struct testcase *test = (struct testcase *)p; 5447735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge int *ip = (*test->func)(); 5547735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge int here = 0; 5647735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge int i; 5747735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 5847735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge for(i = 0; i < COUNT; i++) { 5947735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge int a = (*ip)++; 6047735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge int b = here++; 6147735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge if (a != b) 6247735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge printf("tls_ptr: case \"%s\" has mismatch: *ip=%d here=%d\n", 6347735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge test->name, a, b); 6447735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge nanosleep(&awhile, 0); 6547735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge } 6647735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 6747735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge return 0; 6847735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge} 6947735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 7047735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardingeint *test_so_extern(void); 7147735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardingeint *test_so_local(void); 7247735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardingeint *test_so_global(void); 7347735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 7447735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardingestatic const struct testcase tests[] = { 7547735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge#define T(t) { #t, test_##t } 7647735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge T(race), 7747735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge T(local), 7847735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge T(global), 7947735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge T(static_extern), 8047735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge T(so_extern), 8147735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge T(so_local), 8247735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge T(so_global), 8347735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge#undef T 8447735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge}; 8547735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 8647735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge#define NTESTS (sizeof(tests)/sizeof(*tests)) 8747735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 8847735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardingeint main() 8947735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge{ 9047735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge pthread_t threads[NTESTS*2]; 9147735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge int curthread = 0; 9247735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge static 9347735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge int i; 9447735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 9547735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge for(i = 0; i < NTESTS; i++) { 9647735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge pthread_create(&threads[curthread++], NULL, tls_ptr, (void *)&tests[i]); 9747735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge pthread_create(&threads[curthread++], NULL, tls_ptr, (void *)&tests[i]); 9847735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge } 9947735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 10047735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge for(i = 0; i < curthread; i++) 10147735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge pthread_join(threads[i], NULL); 10247735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge 10347735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge return 0; 10447735af6c44b5f206d5e418aac87a1dbdf9df185fitzhardinge} 105b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj#else 106b5f6f51ebcac183818061bf53427a3e7808ef10dsewardjint main() 107b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj{ 108b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj printf("FAILED: no compiler support for __thread\n"); 109b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj return 1; 110b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj} 111b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj#endif 112