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 */
test_race(void)18 static int *test_race(void)
19 {
20 	return &race;
21 }
22 
test_local(void)23 static int *test_local(void)
24 {
25 	return &local;
26 }
27 
test_global(void)28 static int *test_global(void)
29 {
30 	return &global;
31 }
32 
test_static_extern(void)33 static int *test_static_extern(void)
34 {
35 	return &static_extern;
36 }
37 
test_so_extern(void)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         char pad[2 * (8 - sizeof(void*))];
50 };
tls_ptr(void * p)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 
main()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
main()106 int main()
107 {
108 	printf("FAILED: no compiler support for __thread\n");
109 	return 1;
110 }
111 #endif
112