Home | History | Annotate | Download | only in tests
      1 #include <config.h>
      2 #include <pthread.h>
      3 #include <stdio.h>
      4 #include <unistd.h>
      5 #include <time.h>
      6 
      7 #ifdef HAVE_TLS
      8 
      9 #define COUNT 10
     10 
     11 static int race;
     12 static __thread int local;
     13 __thread int global;
     14 extern __thread int static_extern;
     15 extern __thread int so_extern;
     16 
     17 /* deliberate failure */
     18 static int *test_race(void)
     19 {
     20 	return &race;
     21 }
     22 
     23 static int *test_local(void)
     24 {
     25 	return &local;
     26 }
     27 
     28 static int *test_global(void)
     29 {
     30 	return &global;
     31 }
     32 
     33 static int *test_static_extern(void)
     34 {
     35 	return &static_extern;
     36 }
     37 
     38 static int *test_so_extern(void)
     39 {
     40 	return &so_extern;
     41 }
     42 
     43 static const struct timespec awhile = { 0, 200000000 };
     44 
     45 typedef int *(*func_t)(void);
     46 struct testcase {
     47 	const char *name;
     48 	func_t func;
     49 };
     50 
     51 static void *tls_ptr(void *p)
     52 {
     53 	struct testcase *test = (struct testcase *)p;
     54 	int *ip = (*test->func)();
     55 	int here = 0;
     56 	int i;
     57 
     58 	for(i = 0; i < COUNT; i++) {
     59 		int a = (*ip)++;
     60 		int b = here++;
     61 		if (a != b)
     62 			printf("tls_ptr: case \"%s\" has mismatch: *ip=%d here=%d\n",
     63 			       test->name, a, b);
     64 		nanosleep(&awhile, 0);
     65 	}
     66 
     67 	return 0;
     68 }
     69 
     70 int *test_so_extern(void);
     71 int *test_so_local(void);
     72 int *test_so_global(void);
     73 
     74 static const struct testcase tests[] = {
     75 #define T(t)	{ #t, test_##t }
     76 	T(race),
     77 	T(local),
     78 	T(global),
     79 	T(static_extern),
     80 	T(so_extern),
     81 	T(so_local),
     82 	T(so_global),
     83 #undef T
     84 };
     85 
     86 #define NTESTS	(sizeof(tests)/sizeof(*tests))
     87 
     88 int main()
     89 {
     90 	pthread_t threads[NTESTS*2];
     91 	int curthread = 0;
     92 	static
     93 	int i;
     94 
     95 	for(i = 0; i < NTESTS; i++) {
     96 		pthread_create(&threads[curthread++], NULL, tls_ptr, (void *)&tests[i]);
     97 		pthread_create(&threads[curthread++], NULL, tls_ptr, (void *)&tests[i]);
     98 	}
     99 
    100 	for(i = 0; i < curthread; i++)
    101 		pthread_join(threads[i], NULL);
    102 
    103 	return 0;
    104 }
    105 #else
    106 int main()
    107 {
    108 	printf("FAILED: no compiler support for __thread\n");
    109 	return 1;
    110 }
    111 #endif
    112