tls.c revision e739ac0589b4fb43561f801c4faba8c1b89f8680
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
11static int race;
12static __thread int local;
13__thread int global;
14extern __thread int static_extern;
15extern __thread int so_extern;
16
17/* deliberate failure */
18static int *test_race(void)
19{
20	return &race;
21}
22
23static int *test_local(void)
24{
25	return &local;
26}
27
28static int *test_global(void)
29{
30	return &global;
31}
32
33static int *test_static_extern(void)
34{
35	return &static_extern;
36}
37
38static int *test_so_extern(void)
39{
40	return &so_extern;
41}
42
43static const struct timespec awhile = { 0, 100000000 };
44
45typedef int *(*func_t)(void);
46struct testcase {
47	const char *name;
48	func_t func;
49};
50
51static 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
70int *test_so_extern(void);
71int *test_so_local(void);
72int *test_so_global(void);
73
74static 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
88int 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
106int main()
107{
108	printf("FAILED: no compiler support for __thread\n");
109	return 1;
110}
111#endif
112